diff --git a/lib/src/sql/id.rs b/lib/src/sql/id.rs index cd9afab6..a2b3beb9 100644 --- a/lib/src/sql/id.rs +++ b/lib/src/sql/id.rs @@ -2,7 +2,7 @@ use crate::cnf::ID_CHARS; use crate::sql::error::IResult; use crate::sql::escape::escape_ident; use crate::sql::ident::ident_raw; -use crate::sql::number::{number, Number}; +use crate::sql::number::integer; use nanoid::nanoid; use nom::branch::alt; use nom::combinator::map; @@ -11,16 +11,28 @@ use std::fmt; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum Id { - Number(Number), + Number(i64), String(String), } -impl From for Id { - fn from(v: Number) -> Self { +impl From for Id { + fn from(v: i64) -> Self { Id::Number(v) } } +impl From for Id { + fn from(v: i32) -> Self { + Id::Number(v as i64) + } +} + +impl From for Id { + fn from(v: u64) -> Self { + Id::Number(v as i64) + } +} + impl From for Id { fn from(v: String) -> Self { Id::String(v) @@ -33,12 +45,6 @@ impl From<&str> for Id { } } -impl From for Id { - fn from(v: u64) -> Self { - Id::Number(Number::from(v)) - } -} - impl Id { pub fn rand() -> Id { Id::String(nanoid!(20, &ID_CHARS)) @@ -55,7 +61,7 @@ impl fmt::Display for 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)] diff --git a/lib/src/sql/number.rs b/lib/src/sql/number.rs index 1ec2db38..521ec047 100644 --- a/lib/src/sql/number.rs +++ b/lib/src/sql/number.rs @@ -160,6 +160,18 @@ impl Number { // 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 { match self { Number::Int(v) => v != &0, @@ -492,10 +504,10 @@ impl<'a> Product<&'a Self> for 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, _) = peek(alt(( map(multispace1, |_| ()), @@ -509,10 +521,10 @@ fn integer(i: &str) -> IResult<&str, Number> { map(char(','), |_| ()), map(eof, |_| ()), )))(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, _) = peek(alt(( map(multispace1, |_| ()), @@ -526,7 +538,7 @@ fn decimal(i: &str) -> IResult<&str, Number> { map(char(','), |_| ()), map(eof, |_| ()), )))(i)?; - Ok((i, Number::from(v))) + Ok((i, v)) } #[cfg(test)] diff --git a/lib/src/sql/thing.rs b/lib/src/sql/thing.rs index 92fead72..a0589a49 100644 --- a/lib/src/sql/thing.rs +++ b/lib/src/sql/thing.rs @@ -2,7 +2,6 @@ use crate::sql::error::IResult; use crate::sql::escape::escape_ident; use crate::sql::id::{id, Id}; use crate::sql::ident::ident_raw; -use crate::sql::number::Number; use crate::sql::serde::is_internal_serialization; use derive::Store; 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 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}:{}", escape_ident(&self.tb), self.id) diff --git a/lib/src/sql/value/retable.rs b/lib/src/sql/value/retable.rs index dd653cca..ccf900c3 100644 --- a/lib/src/sql/value/retable.rs +++ b/lib/src/sql/value/retable.rs @@ -12,14 +12,18 @@ impl Value { pub fn retable(&self, val: &Table) -> Result { // Fetch the id from the document 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 { tb: val.to_string(), id: Id::String(id.0), }, - Value::Number(id) => Thing { - tb: val.to_string(), - id: Id::Number(id), - }, Value::Thing(id) => Thing { tb: val.to_string(), id: id.id, diff --git a/lib/src/sql/value/value.rs b/lib/src/sql/value/value.rs index 4e92a8f6..b305422a 100644 --- a/lib/src/sql/value/value.rs +++ b/lib/src/sql/value/value.rs @@ -1352,7 +1352,8 @@ mod tests { #[test] fn check_size() { - assert_eq!(88, std::mem::size_of::()); + assert_eq!(64, std::mem::size_of::()); + assert_eq!(88, std::mem::size_of::>()); assert_eq!(48, std::mem::size_of::()); assert_eq!(24, std::mem::size_of::()); assert_eq!(16, std::mem::size_of::()); @@ -1363,13 +1364,12 @@ mod tests { assert_eq!(24, std::mem::size_of::()); assert_eq!(24, std::mem::size_of::()); assert_eq!(24, std::mem::size_of::()); - assert_eq!(80, std::mem::size_of::()); + assert_eq!(56, std::mem::size_of::()); assert_eq!(48, std::mem::size_of::()); assert_eq!(24, std::mem::size_of::()); assert_eq!(8, std::mem::size_of::>()); assert_eq!(8, std::mem::size_of::>()); assert_eq!(8, std::mem::size_of::>()); - assert_eq!(96, std::mem::size_of::>()); } #[test]