Only support strings or integers for Record IDs
This commit is contained in:
parent
2c97d65e97
commit
a8fa9ecfb7
5 changed files with 45 additions and 33 deletions
|
@ -2,7 +2,7 @@ use crate::cnf::ID_CHARS;
|
||||||
use crate::sql::error::IResult;
|
use crate::sql::error::IResult;
|
||||||
use crate::sql::escape::escape_ident;
|
use crate::sql::escape::escape_ident;
|
||||||
use crate::sql::ident::ident_raw;
|
use crate::sql::ident::ident_raw;
|
||||||
use crate::sql::number::{number, Number};
|
use crate::sql::number::integer;
|
||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
|
@ -11,16 +11,28 @@ use std::fmt;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
pub enum Id {
|
pub enum Id {
|
||||||
Number(Number),
|
Number(i64),
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Number> for Id {
|
impl From<i64> for Id {
|
||||||
fn from(v: Number) -> Self {
|
fn from(v: i64) -> Self {
|
||||||
Id::Number(v)
|
Id::Number(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i32> for Id {
|
||||||
|
fn from(v: i32) -> Self {
|
||||||
|
Id::Number(v as i64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u64> for Id {
|
||||||
|
fn from(v: u64) -> Self {
|
||||||
|
Id::Number(v as i64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<String> for Id {
|
impl From<String> for Id {
|
||||||
fn from(v: String) -> Self {
|
fn from(v: String) -> Self {
|
||||||
Id::String(v)
|
Id::String(v)
|
||||||
|
@ -33,12 +45,6 @@ impl From<&str> for Id {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u64> for Id {
|
|
||||||
fn from(v: u64) -> Self {
|
|
||||||
Id::Number(Number::from(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Id {
|
impl Id {
|
||||||
pub fn rand() -> Id {
|
pub fn rand() -> Id {
|
||||||
Id::String(nanoid!(20, &ID_CHARS))
|
Id::String(nanoid!(20, &ID_CHARS))
|
||||||
|
@ -55,7 +61,7 @@ impl fmt::Display for Id {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(i: &str) -> IResult<&str, Id> {
|
pub fn id(i: &str) -> IResult<&str, Id> {
|
||||||
alt((map(number, Id::Number), map(ident_raw, Id::String)))(i)
|
alt((map(integer, Id::Number), map(ident_raw, Id::String)))(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -160,6 +160,18 @@ impl Number {
|
||||||
// Simple number detection
|
// Simple number detection
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
||||||
|
pub fn is_int(&self) -> bool {
|
||||||
|
matches!(self, Number::Int(_))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_float(&self) -> bool {
|
||||||
|
matches!(self, Number::Float(_))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_decimal(&self) -> bool {
|
||||||
|
matches!(self, Number::Decimal(_))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_truthy(&self) -> bool {
|
pub fn is_truthy(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Number::Int(v) => v != &0,
|
Number::Int(v) => v != &0,
|
||||||
|
@ -492,10 +504,10 @@ impl<'a> Product<&'a Self> for Number {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn number(i: &str) -> IResult<&str, Number> {
|
pub fn number(i: &str) -> IResult<&str, Number> {
|
||||||
alt((integer, decimal))(i)
|
alt((map(integer, Number::from), map(decimal, Number::from)))(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn integer(i: &str) -> IResult<&str, Number> {
|
pub fn integer(i: &str) -> IResult<&str, i64> {
|
||||||
let (i, v) = i64(i)?;
|
let (i, v) = i64(i)?;
|
||||||
let (i, _) = peek(alt((
|
let (i, _) = peek(alt((
|
||||||
map(multispace1, |_| ()),
|
map(multispace1, |_| ()),
|
||||||
|
@ -509,10 +521,10 @@ fn integer(i: &str) -> IResult<&str, Number> {
|
||||||
map(char(','), |_| ()),
|
map(char(','), |_| ()),
|
||||||
map(eof, |_| ()),
|
map(eof, |_| ()),
|
||||||
)))(i)?;
|
)))(i)?;
|
||||||
Ok((i, Number::from(v)))
|
Ok((i, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decimal(i: &str) -> IResult<&str, Number> {
|
pub fn decimal(i: &str) -> IResult<&str, &str> {
|
||||||
let (i, v) = recognize_float(i)?;
|
let (i, v) = recognize_float(i)?;
|
||||||
let (i, _) = peek(alt((
|
let (i, _) = peek(alt((
|
||||||
map(multispace1, |_| ()),
|
map(multispace1, |_| ()),
|
||||||
|
@ -526,7 +538,7 @@ fn decimal(i: &str) -> IResult<&str, Number> {
|
||||||
map(char(','), |_| ()),
|
map(char(','), |_| ()),
|
||||||
map(eof, |_| ()),
|
map(eof, |_| ()),
|
||||||
)))(i)?;
|
)))(i)?;
|
||||||
Ok((i, Number::from(v)))
|
Ok((i, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -2,7 +2,6 @@ use crate::sql::error::IResult;
|
||||||
use crate::sql::escape::escape_ident;
|
use crate::sql::escape::escape_ident;
|
||||||
use crate::sql::id::{id, Id};
|
use crate::sql::id::{id, Id};
|
||||||
use crate::sql::ident::ident_raw;
|
use crate::sql::ident::ident_raw;
|
||||||
use crate::sql::number::Number;
|
|
||||||
use crate::sql::serde::is_internal_serialization;
|
use crate::sql::serde::is_internal_serialization;
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
|
@ -34,15 +33,6 @@ impl From<(String, String)> for Thing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(String, Number)> for Thing {
|
|
||||||
fn from(v: (String, Number)) -> Self {
|
|
||||||
Thing {
|
|
||||||
tb: v.0,
|
|
||||||
id: Id::from(v.1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Thing {
|
impl fmt::Display for Thing {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}:{}", escape_ident(&self.tb), self.id)
|
write!(f, "{}:{}", escape_ident(&self.tb), self.id)
|
||||||
|
|
|
@ -12,14 +12,18 @@ impl Value {
|
||||||
pub fn retable(&self, val: &Table) -> Result<Thing, Error> {
|
pub fn retable(&self, val: &Table) -> Result<Thing, Error> {
|
||||||
// Fetch the id from the document
|
// Fetch the id from the document
|
||||||
let id = match self.pick(&*ID) {
|
let id = match self.pick(&*ID) {
|
||||||
|
Value::Number(id) if id.is_float() => Thing {
|
||||||
|
tb: val.to_string(),
|
||||||
|
id: Id::Number(id.as_int()),
|
||||||
|
},
|
||||||
|
Value::Number(id) if id.is_int() => Thing {
|
||||||
|
tb: val.to_string(),
|
||||||
|
id: Id::Number(id.as_int()),
|
||||||
|
},
|
||||||
Value::Strand(id) => Thing {
|
Value::Strand(id) => Thing {
|
||||||
tb: val.to_string(),
|
tb: val.to_string(),
|
||||||
id: Id::String(id.0),
|
id: Id::String(id.0),
|
||||||
},
|
},
|
||||||
Value::Number(id) => Thing {
|
|
||||||
tb: val.to_string(),
|
|
||||||
id: Id::Number(id),
|
|
||||||
},
|
|
||||||
Value::Thing(id) => Thing {
|
Value::Thing(id) => Thing {
|
||||||
tb: val.to_string(),
|
tb: val.to_string(),
|
||||||
id: id.id,
|
id: id.id,
|
||||||
|
|
|
@ -1352,7 +1352,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_size() {
|
fn check_size() {
|
||||||
assert_eq!(88, std::mem::size_of::<Value>());
|
assert_eq!(64, std::mem::size_of::<Value>());
|
||||||
|
assert_eq!(88, std::mem::size_of::<Result<Value, Error>>());
|
||||||
assert_eq!(48, std::mem::size_of::<crate::sql::number::Number>());
|
assert_eq!(48, std::mem::size_of::<crate::sql::number::Number>());
|
||||||
assert_eq!(24, std::mem::size_of::<crate::sql::strand::Strand>());
|
assert_eq!(24, std::mem::size_of::<crate::sql::strand::Strand>());
|
||||||
assert_eq!(16, std::mem::size_of::<crate::sql::duration::Duration>());
|
assert_eq!(16, std::mem::size_of::<crate::sql::duration::Duration>());
|
||||||
|
@ -1363,13 +1364,12 @@ mod tests {
|
||||||
assert_eq!(24, std::mem::size_of::<crate::sql::param::Param>());
|
assert_eq!(24, std::mem::size_of::<crate::sql::param::Param>());
|
||||||
assert_eq!(24, std::mem::size_of::<crate::sql::idiom::Idiom>());
|
assert_eq!(24, std::mem::size_of::<crate::sql::idiom::Idiom>());
|
||||||
assert_eq!(24, std::mem::size_of::<crate::sql::table::Table>());
|
assert_eq!(24, std::mem::size_of::<crate::sql::table::Table>());
|
||||||
assert_eq!(80, std::mem::size_of::<crate::sql::thing::Thing>());
|
assert_eq!(56, std::mem::size_of::<crate::sql::thing::Thing>());
|
||||||
assert_eq!(48, std::mem::size_of::<crate::sql::model::Model>());
|
assert_eq!(48, std::mem::size_of::<crate::sql::model::Model>());
|
||||||
assert_eq!(24, std::mem::size_of::<crate::sql::regex::Regex>());
|
assert_eq!(24, std::mem::size_of::<crate::sql::regex::Regex>());
|
||||||
assert_eq!(8, std::mem::size_of::<Box<crate::sql::function::Function>>());
|
assert_eq!(8, std::mem::size_of::<Box<crate::sql::function::Function>>());
|
||||||
assert_eq!(8, std::mem::size_of::<Box<crate::sql::subquery::Subquery>>());
|
assert_eq!(8, std::mem::size_of::<Box<crate::sql::subquery::Subquery>>());
|
||||||
assert_eq!(8, std::mem::size_of::<Box<crate::sql::expression::Expression>>());
|
assert_eq!(8, std::mem::size_of::<Box<crate::sql::expression::Expression>>());
|
||||||
assert_eq!(96, std::mem::size_of::<Result<Value, Error>>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue