From 45e1a9adce0d63221e3b6b124d5774e4f7aed73f Mon Sep 17 00:00:00 2001 From: Finn Bear Date: Tue, 4 Oct 2022 14:51:18 -0700 Subject: [PATCH] Refactor, optimization, cleanup (#1288) --- lib/src/sql/algorithm.rs | 30 +-- lib/src/sql/array.rs | 43 ++-- lib/src/sql/base.rs | 12 +- lib/src/sql/constant.rs | 156 ++++++------ lib/src/sql/data.rs | 74 +++--- lib/src/sql/datetime.rs | 12 +- lib/src/sql/dir.rs | 10 +- lib/src/sql/duration.rs | 4 +- lib/src/sql/error.rs | 2 +- lib/src/sql/expression.rs | 10 +- lib/src/sql/fetch.rs | 15 +- lib/src/sql/field.rs | 23 +- lib/src/sql/fmt.rs | 45 ++++ lib/src/sql/function.rs | 91 ++++--- lib/src/sql/geometry.rs | 392 ++++++++++++++++--------------- lib/src/sql/graph.rs | 18 +- lib/src/sql/group.rs | 19 +- lib/src/sql/id.rs | 44 ++-- lib/src/sql/ident.rs | 14 +- lib/src/sql/idiom.rs | 13 +- lib/src/sql/kind.rs | 23 +- lib/src/sql/mod.rs | 1 + lib/src/sql/number.rs | 39 ++- lib/src/sql/object.rs | 20 +- lib/src/sql/operator.rs | 70 +++--- lib/src/sql/order.rs | 7 +- lib/src/sql/output.rs | 20 +- lib/src/sql/param.rs | 4 +- lib/src/sql/parser.rs | 4 +- lib/src/sql/part.rs | 28 +-- lib/src/sql/permission.rs | 8 +- lib/src/sql/query.rs | 8 +- lib/src/sql/regex.rs | 4 +- lib/src/sql/script.rs | 12 +- lib/src/sql/split.rs | 15 +- lib/src/sql/statement.rs | 121 +++++----- lib/src/sql/statements/begin.rs | 2 +- lib/src/sql/statements/cancel.rs | 2 +- lib/src/sql/statements/commit.rs | 2 +- lib/src/sql/statements/create.rs | 2 +- lib/src/sql/statements/define.rs | 37 +-- lib/src/sql/statements/delete.rs | 2 +- lib/src/sql/statements/info.rs | 10 +- lib/src/sql/statements/insert.rs | 6 +- lib/src/sql/statements/relate.rs | 4 +- lib/src/sql/statements/remove.rs | 42 ++-- lib/src/sql/statements/select.rs | 2 +- lib/src/sql/statements/update.rs | 2 +- lib/src/sql/statements/yuse.rs | 2 +- lib/src/sql/strand.rs | 10 +- lib/src/sql/subquery.rs | 54 ++--- lib/src/sql/table.rs | 21 +- lib/src/sql/test.rs | 28 +-- lib/src/sql/thing.rs | 22 +- lib/src/sql/uuid.rs | 4 +- lib/src/sql/value/value.rs | 9 +- 56 files changed, 850 insertions(+), 824 deletions(-) create mode 100644 lib/src/sql/fmt.rs diff --git a/lib/src/sql/algorithm.rs b/lib/src/sql/algorithm.rs index d42f2e82..ba07df84 100644 --- a/lib/src/sql/algorithm.rs +++ b/lib/src/sql/algorithm.rs @@ -23,27 +23,27 @@ pub enum Algorithm { } impl Default for Algorithm { - fn default() -> Algorithm { - Algorithm::Hs512 + fn default() -> Self { + Self::Hs512 } } impl fmt::Display for Algorithm { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match self { - Algorithm::EdDSA => "EDDSA", - Algorithm::Es256 => "ES256", - Algorithm::Es384 => "ES384", - Algorithm::Es512 => "ES512", - Algorithm::Hs256 => "HS256", - Algorithm::Hs384 => "HS384", - Algorithm::Hs512 => "HS512", - Algorithm::Ps256 => "PS256", - Algorithm::Ps384 => "PS384", - Algorithm::Ps512 => "PS512", - Algorithm::Rs256 => "RS256", - Algorithm::Rs384 => "RS384", - Algorithm::Rs512 => "RS512", + Self::EdDSA => "EDDSA", + Self::Es256 => "ES256", + Self::Es384 => "ES384", + Self::Es512 => "ES512", + Self::Hs256 => "HS256", + Self::Hs384 => "HS384", + Self::Hs512 => "HS512", + Self::Ps256 => "PS256", + Self::Ps384 => "PS384", + Self::Ps512 => "PS512", + Self::Rs256 => "RS256", + Self::Rs384 => "RS384", + Self::Rs512 => "RS512", }) } } diff --git a/lib/src/sql/array.rs b/lib/src/sql/array.rs index daf0ee1b..03e22d52 100644 --- a/lib/src/sql/array.rs +++ b/lib/src/sql/array.rs @@ -5,6 +5,7 @@ use crate::err::Error; use crate::sql::comment::mightbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::number::Number; use crate::sql::operation::Operation; use crate::sql::serde::is_internal_serialization; @@ -14,7 +15,7 @@ use nom::character::complete::char; use nom::combinator::opt; use nom::multi::separated_list0; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops; use std::ops::Deref; use std::ops::DerefMut; @@ -24,37 +25,37 @@ pub struct Array(pub Vec); impl From for Array { fn from(v: Value) -> Self { - Array(vec![v]) + vec![v].into() } } impl From> for Array { fn from(v: Vec) -> Self { - Array(v) + Self(v) } } impl From> for Array { fn from(v: Vec) -> Self { - Array(v.into_iter().map(Value::from).collect()) + Self(v.into_iter().map(Value::from).collect()) } } impl From> for Array { fn from(v: Vec<&str>) -> Self { - Array(v.into_iter().map(Value::from).collect()) + Self(v.into_iter().map(Value::from).collect()) } } impl From> for Array { fn from(v: Vec) -> Self { - Array(v.into_iter().map(Value::from).collect()) + Self(v.into_iter().map(Value::from).collect()) } } impl From> for Array { fn from(v: Vec) -> Self { - Array(v.into_iter().map(Value::from).collect()) + Self(v.into_iter().map(Value::from).collect()) } } @@ -81,11 +82,11 @@ impl IntoIterator for Array { impl Array { pub fn new() -> Self { - Array(Vec::default()) + Self::default() } pub fn with_capacity(len: usize) -> Self { - Array(Vec::with_capacity(len)) + Self(Vec::with_capacity(len)) } pub fn as_ints(self) -> Vec { @@ -121,20 +122,20 @@ impl Array { txn: &Transaction, doc: Option<&Value>, ) -> Result { - let mut x = Vec::new(); + let mut x = Self::with_capacity(self.len()); for v in self.iter() { match v.compute(ctx, opt, txn, doc).await { Ok(v) => x.push(v), Err(e) => return Err(e), }; } - Ok(Value::Array(Array(x))) + Ok(Value::Array(x)) } } -impl fmt::Display for Array { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "[{}]", self.iter().map(|ref v| format!("{}", v)).collect::>().join(", ")) +impl Display for Array { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "[{}]", Fmt::comma_separated(self.as_slice())) } } @@ -230,8 +231,8 @@ pub trait Combine { } impl Combine for Array { - fn combine(self, other: Array) -> Array { - let mut out = Array::new(); + fn combine(self, other: Self) -> Array { + let mut out = Self::with_capacity(self.len().saturating_mul(other.len())); for a in self.iter() { for b in other.iter() { out.push(vec![a.clone(), b.clone()].into()); @@ -282,9 +283,9 @@ pub trait Intersect { fn intersect(self, other: T) -> T; } -impl Intersect for Array { - fn intersect(self, other: Array) -> Array { - let mut out = Array::new(); +impl Intersect for Array { + fn intersect(self, other: Self) -> Self { + let mut out = Self::new(); let mut other: Vec<_> = other.into_iter().collect(); for a in self.0.into_iter() { if let Some(pos) = other.iter().position(|b| a == *b) { @@ -302,8 +303,8 @@ pub trait Union { fn union(self, other: T) -> T; } -impl Union for Array { - fn union(mut self, mut other: Array) -> Array { +impl Union for Array { + fn union(mut self, mut other: Self) -> Array { self.append(&mut other); self.uniq() } diff --git a/lib/src/sql/base.rs b/lib/src/sql/base.rs index 47f84934..d56081cf 100644 --- a/lib/src/sql/base.rs +++ b/lib/src/sql/base.rs @@ -16,18 +16,18 @@ pub enum Base { } impl Default for Base { - fn default() -> Base { - Base::Kv + fn default() -> Self { + Self::Kv } } impl fmt::Display for Base { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Base::Ns => write!(f, "NAMESPACE"), - Base::Db => write!(f, "DATABASE"), - Base::Sc(sc) => write!(f, "SCOPE {}", sc), - _ => write!(f, "KV"), + Self::Ns => f.write_str("NAMESPACE"), + Self::Db => f.write_str("DATABASE"), + Self::Sc(sc) => write!(f, "SCOPE {}", sc), + Self::Kv => f.write_str("KV"), } } } diff --git a/lib/src/sql/constant.rs b/lib/src/sql/constant.rs index 4ab858fd..b6ef0b9a 100644 --- a/lib/src/sql/constant.rs +++ b/lib/src/sql/constant.rs @@ -43,52 +43,52 @@ impl Constant { _txn: &Transaction, _doc: Option<&Value>, ) -> Result { - match self { - Constant::MathE => Ok(std::f64::consts::E.into()), - Constant::MathFrac1Pi => Ok(std::f64::consts::FRAC_1_PI.into()), - Constant::MathFrac1Sqrt2 => Ok(std::f64::consts::FRAC_1_SQRT_2.into()), - Constant::MathFrac2Pi => Ok(std::f64::consts::FRAC_2_PI.into()), - Constant::MathFrac2SqrtPi => Ok(std::f64::consts::FRAC_2_SQRT_PI.into()), - Constant::MathFracPi2 => Ok(std::f64::consts::FRAC_PI_2.into()), - Constant::MathFracPi3 => Ok(std::f64::consts::FRAC_PI_3.into()), - Constant::MathFracPi4 => Ok(std::f64::consts::FRAC_PI_4.into()), - Constant::MathFracPi6 => Ok(std::f64::consts::FRAC_PI_6.into()), - Constant::MathFracPi8 => Ok(std::f64::consts::FRAC_PI_8.into()), - Constant::MathLn10 => Ok(std::f64::consts::LN_10.into()), - Constant::MathLn2 => Ok(std::f64::consts::LN_2.into()), - Constant::MathLog102 => Ok(std::f64::consts::LOG10_2.into()), - Constant::MathLog10E => Ok(std::f64::consts::LOG10_E.into()), - Constant::MathLog210 => Ok(std::f64::consts::LOG2_10.into()), - Constant::MathLog2E => Ok(std::f64::consts::LOG2_E.into()), - Constant::MathPi => Ok(std::f64::consts::PI.into()), - Constant::MathSqrt2 => Ok(std::f64::consts::SQRT_2.into()), - Constant::MathTau => Ok(std::f64::consts::TAU.into()), - } + Ok(match self { + Self::MathE => std::f64::consts::E.into(), + Self::MathFrac1Pi => std::f64::consts::FRAC_1_PI.into(), + Self::MathFrac1Sqrt2 => std::f64::consts::FRAC_1_SQRT_2.into(), + Self::MathFrac2Pi => std::f64::consts::FRAC_2_PI.into(), + Self::MathFrac2SqrtPi => std::f64::consts::FRAC_2_SQRT_PI.into(), + Self::MathFracPi2 => std::f64::consts::FRAC_PI_2.into(), + Self::MathFracPi3 => std::f64::consts::FRAC_PI_3.into(), + Self::MathFracPi4 => std::f64::consts::FRAC_PI_4.into(), + Self::MathFracPi6 => std::f64::consts::FRAC_PI_6.into(), + Self::MathFracPi8 => std::f64::consts::FRAC_PI_8.into(), + Self::MathLn10 => std::f64::consts::LN_10.into(), + Self::MathLn2 => std::f64::consts::LN_2.into(), + Self::MathLog102 => std::f64::consts::LOG10_2.into(), + Self::MathLog10E => std::f64::consts::LOG10_E.into(), + Self::MathLog210 => std::f64::consts::LOG2_10.into(), + Self::MathLog2E => std::f64::consts::LOG2_E.into(), + Self::MathPi => std::f64::consts::PI.into(), + Self::MathSqrt2 => std::f64::consts::SQRT_2.into(), + Self::MathTau => std::f64::consts::TAU.into(), + }) } } impl fmt::Display for Constant { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match self { - Constant::MathE => "math::E", - Constant::MathFrac1Pi => "math::FRAC_1_PI", - Constant::MathFrac1Sqrt2 => "math::FRAC_1_SQRT_2", - Constant::MathFrac2Pi => "math::FRAC_2_PI", - Constant::MathFrac2SqrtPi => "math::FRAC_2_SQRT_PI", - Constant::MathFracPi2 => "math::FRAC_PI_2", - Constant::MathFracPi3 => "math::FRAC_PI_3", - Constant::MathFracPi4 => "math::FRAC_PI_4", - Constant::MathFracPi6 => "math::FRAC_PI_6", - Constant::MathFracPi8 => "math::FRAC_PI_8", - Constant::MathLn10 => "math::LN_10", - Constant::MathLn2 => "math::LN_2", - Constant::MathLog102 => "math::LOG10_2", - Constant::MathLog10E => "math::LOG10_E", - Constant::MathLog210 => "math::LOG2_10", - Constant::MathLog2E => "math::LOG2_E", - Constant::MathPi => "math::PI", - Constant::MathSqrt2 => "math::SQRT_2", - Constant::MathTau => "math::TAU", + Self::MathE => "math::E", + Self::MathFrac1Pi => "math::FRAC_1_PI", + Self::MathFrac1Sqrt2 => "math::FRAC_1_SQRT_2", + Self::MathFrac2Pi => "math::FRAC_2_PI", + Self::MathFrac2SqrtPi => "math::FRAC_2_SQRT_PI", + Self::MathFracPi2 => "math::FRAC_PI_2", + Self::MathFracPi3 => "math::FRAC_PI_3", + Self::MathFracPi4 => "math::FRAC_PI_4", + Self::MathFracPi6 => "math::FRAC_PI_6", + Self::MathFracPi8 => "math::FRAC_PI_8", + Self::MathLn10 => "math::LN_10", + Self::MathLn2 => "math::LN_2", + Self::MathLog102 => "math::LOG10_2", + Self::MathLog10E => "math::LOG10_E", + Self::MathLog210 => "math::LOG2_10", + Self::MathLog2E => "math::LOG2_E", + Self::MathPi => "math::PI", + Self::MathSqrt2 => "math::SQRT_2", + Self::MathTau => "math::TAU", }) } } @@ -101,47 +101,47 @@ impl Serialize for Constant { { if is_internal_serialization() { match self { - Constant::MathE => s.serialize_unit_variant("Constant", 0, "MathE"), - Constant::MathFrac1Pi => s.serialize_unit_variant("Constant", 1, "MathFrac1Pi"), - Constant::MathFrac1Sqrt2 => s.serialize_unit_variant("Constant", 2, "MathFrac1Sqrt2"), - Constant::MathFrac2Pi => s.serialize_unit_variant("Constant", 3, "MathFrac2Pi"), - Constant::MathFrac2SqrtPi => s.serialize_unit_variant("Constant", 4, "MathFrac2SqrtPi"), - Constant::MathFracPi2 => s.serialize_unit_variant("Constant", 5, "MathFracPi2"), - Constant::MathFracPi3 => s.serialize_unit_variant("Constant", 6, "MathFracPi3"), - Constant::MathFracPi4 => s.serialize_unit_variant("Constant", 7, "MathFracPi4"), - Constant::MathFracPi6 => s.serialize_unit_variant("Constant", 8, "MathFracPi6"), - Constant::MathFracPi8 => s.serialize_unit_variant("Constant", 9, "MathFracPi8"), - Constant::MathLn10 => s.serialize_unit_variant("Constant", 10, "MathLn10"), - Constant::MathLn2 => s.serialize_unit_variant("Constant", 11, "MathLn2"), - Constant::MathLog102 => s.serialize_unit_variant("Constant", 12, "MathLog102"), - Constant::MathLog10E => s.serialize_unit_variant("Constant", 13, "MathLog10E"), - Constant::MathLog210 => s.serialize_unit_variant("Constant", 14, "MathLog210"), - Constant::MathLog2E => s.serialize_unit_variant("Constant", 15, "MathLog2E"), - Constant::MathPi => s.serialize_unit_variant("Constant", 16, "MathPi"), - Constant::MathSqrt2 => s.serialize_unit_variant("Constant", 17, "MathSqrt2"), - Constant::MathTau => s.serialize_unit_variant("Constant", 18, "MathTau"), + Self::MathE => s.serialize_unit_variant("Constant", 0, "MathE"), + Self::MathFrac1Pi => s.serialize_unit_variant("Constant", 1, "MathFrac1Pi"), + Self::MathFrac1Sqrt2 => s.serialize_unit_variant("Constant", 2, "MathFrac1Sqrt2"), + Self::MathFrac2Pi => s.serialize_unit_variant("Constant", 3, "MathFrac2Pi"), + Self::MathFrac2SqrtPi => s.serialize_unit_variant("Constant", 4, "MathFrac2SqrtPi"), + Self::MathFracPi2 => s.serialize_unit_variant("Constant", 5, "MathFracPi2"), + Self::MathFracPi3 => s.serialize_unit_variant("Constant", 6, "MathFracPi3"), + Self::MathFracPi4 => s.serialize_unit_variant("Constant", 7, "MathFracPi4"), + Self::MathFracPi6 => s.serialize_unit_variant("Constant", 8, "MathFracPi6"), + Self::MathFracPi8 => s.serialize_unit_variant("Constant", 9, "MathFracPi8"), + Self::MathLn10 => s.serialize_unit_variant("Constant", 10, "MathLn10"), + Self::MathLn2 => s.serialize_unit_variant("Constant", 11, "MathLn2"), + Self::MathLog102 => s.serialize_unit_variant("Constant", 12, "MathLog102"), + Self::MathLog10E => s.serialize_unit_variant("Constant", 13, "MathLog10E"), + Self::MathLog210 => s.serialize_unit_variant("Constant", 14, "MathLog210"), + Self::MathLog2E => s.serialize_unit_variant("Constant", 15, "MathLog2E"), + Self::MathPi => s.serialize_unit_variant("Constant", 16, "MathPi"), + Self::MathSqrt2 => s.serialize_unit_variant("Constant", 17, "MathSqrt2"), + Self::MathTau => s.serialize_unit_variant("Constant", 18, "MathTau"), } } else { match self { - Constant::MathE => s.serialize_f64(std::f64::consts::E), - Constant::MathFrac1Pi => s.serialize_f64(std::f64::consts::FRAC_1_PI), - Constant::MathFrac1Sqrt2 => s.serialize_f64(std::f64::consts::FRAC_1_SQRT_2), - Constant::MathFrac2Pi => s.serialize_f64(std::f64::consts::FRAC_2_PI), - Constant::MathFrac2SqrtPi => s.serialize_f64(std::f64::consts::FRAC_2_SQRT_PI), - Constant::MathFracPi2 => s.serialize_f64(std::f64::consts::FRAC_PI_2), - Constant::MathFracPi3 => s.serialize_f64(std::f64::consts::FRAC_PI_3), - Constant::MathFracPi4 => s.serialize_f64(std::f64::consts::FRAC_PI_4), - Constant::MathFracPi6 => s.serialize_f64(std::f64::consts::FRAC_PI_6), - Constant::MathFracPi8 => s.serialize_f64(std::f64::consts::FRAC_PI_8), - Constant::MathLn10 => s.serialize_f64(std::f64::consts::LN_10), - Constant::MathLn2 => s.serialize_f64(std::f64::consts::LN_2), - Constant::MathLog102 => s.serialize_f64(std::f64::consts::LOG10_2), - Constant::MathLog10E => s.serialize_f64(std::f64::consts::LOG10_E), - Constant::MathLog210 => s.serialize_f64(std::f64::consts::LOG2_10), - Constant::MathLog2E => s.serialize_f64(std::f64::consts::LOG2_E), - Constant::MathPi => s.serialize_f64(std::f64::consts::PI), - Constant::MathSqrt2 => s.serialize_f64(std::f64::consts::SQRT_2), - Constant::MathTau => s.serialize_f64(std::f64::consts::TAU), + Self::MathE => s.serialize_f64(std::f64::consts::E), + Self::MathFrac1Pi => s.serialize_f64(std::f64::consts::FRAC_1_PI), + Self::MathFrac1Sqrt2 => s.serialize_f64(std::f64::consts::FRAC_1_SQRT_2), + Self::MathFrac2Pi => s.serialize_f64(std::f64::consts::FRAC_2_PI), + Self::MathFrac2SqrtPi => s.serialize_f64(std::f64::consts::FRAC_2_SQRT_PI), + Self::MathFracPi2 => s.serialize_f64(std::f64::consts::FRAC_PI_2), + Self::MathFracPi3 => s.serialize_f64(std::f64::consts::FRAC_PI_3), + Self::MathFracPi4 => s.serialize_f64(std::f64::consts::FRAC_PI_4), + Self::MathFracPi6 => s.serialize_f64(std::f64::consts::FRAC_PI_6), + Self::MathFracPi8 => s.serialize_f64(std::f64::consts::FRAC_PI_8), + Self::MathLn10 => s.serialize_f64(std::f64::consts::LN_10), + Self::MathLn2 => s.serialize_f64(std::f64::consts::LN_2), + Self::MathLog102 => s.serialize_f64(std::f64::consts::LOG10_2), + Self::MathLog10E => s.serialize_f64(std::f64::consts::LOG10_E), + Self::MathLog210 => s.serialize_f64(std::f64::consts::LOG2_10), + Self::MathLog2E => s.serialize_f64(std::f64::consts::LOG2_E), + Self::MathPi => s.serialize_f64(std::f64::consts::PI), + Self::MathSqrt2 => s.serialize_f64(std::f64::consts::SQRT_2), + Self::MathTau => s.serialize_f64(std::f64::consts::TAU), } } } diff --git a/lib/src/sql/data.rs b/lib/src/sql/data.rs index 5092f4a0..8d08e706 100644 --- a/lib/src/sql/data.rs +++ b/lib/src/sql/data.rs @@ -3,6 +3,7 @@ use crate::sql::comment::mightbespace; use crate::sql::comment::shouldbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::idiom::{idiom, Idiom}; use crate::sql::operator::{assigner, Operator}; use crate::sql::table::Table; @@ -12,7 +13,7 @@ use nom::branch::alt; use nom::bytes::complete::tag_no_case; use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum Data { @@ -28,8 +29,8 @@ pub enum Data { } impl Default for Data { - fn default() -> Data { - Data::EmptyExpression + fn default() -> Self { + Self::EmptyExpression } } @@ -37,10 +38,10 @@ impl Data { // Fetch pub(crate) fn rid(&self, tb: &Table) -> Result { match self { - Data::MergeExpression(v) => v.rid().generate(tb, false), - Data::ReplaceExpression(v) => v.rid().generate(tb, false), - Data::ContentExpression(v) => v.rid().generate(tb, false), - Data::SetExpression(v) => match v.iter().find(|f| f.0.is_id()) { + Self::MergeExpression(v) => v.rid().generate(tb, false), + Self::ReplaceExpression(v) => v.rid().generate(tb, false), + Self::ContentExpression(v) => v.rid().generate(tb, false), + Self::SetExpression(v) => match v.iter().find(|f| f.0.is_id()) { Some((_, _, v)) => v.clone().generate(tb, false), _ => Ok(tb.generate()), }, @@ -49,47 +50,42 @@ impl Data { } } -impl fmt::Display for Data { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Data { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Data::EmptyExpression => write!(f, ""), - Data::SetExpression(v) => write!( + Self::EmptyExpression => Ok(()), + Self::SetExpression(v) => write!( f, "SET {}", - v.iter() - .map(|(l, o, r)| format!("{} {} {}", l, o, r)) - .collect::>() - .join(", ") + Fmt::comma_separated(v.iter().map(|args| Fmt::new(args, |(l, o, r), f| write!( + f, + "{} {} {}", + l, o, r + )))) ), - Data::PatchExpression(v) => write!(f, "PATCH {}", v), - Data::MergeExpression(v) => write!(f, "MERGE {}", v), - Data::ReplaceExpression(v) => write!(f, "REPLACE {}", v), - Data::ContentExpression(v) => write!(f, "CONTENT {}", v), - Data::SingleExpression(v) => write!(f, "{}", v), - Data::ValuesExpression(v) => write!( + Self::PatchExpression(v) => write!(f, "PATCH {}", v), + Self::MergeExpression(v) => write!(f, "MERGE {}", v), + Self::ReplaceExpression(v) => write!(f, "REPLACE {}", v), + Self::ContentExpression(v) => write!(f, "CONTENT {}", v), + Self::SingleExpression(v) => Display::fmt(v, f), + Self::ValuesExpression(v) => write!( f, "({}) VALUES {}", - v.first() - .unwrap() - .iter() - .map(|v| format!("{}", v.0)) - .collect::>() - .join(", "), - v.iter() - .map(|v| format!( - "({})", - v.iter().map(|v| format!("{}", v.1)).collect::>().join(", ") - )) - .collect::>() - .join(", ") + Fmt::comma_separated(v.first().unwrap().iter().map(|(v, _)| v)), + Fmt::comma_separated(v.iter().map(|v| Fmt::new(v, |v, f| write!( + f, + "({})", + Fmt::comma_separated(v.iter().map(|(_, v)| v)) + )))) ), - Data::UpdateExpression(v) => write!( + Self::UpdateExpression(v) => write!( f, "ON DUPLICATE KEY UPDATE {}", - v.iter() - .map(|(l, o, r)| format!("{} {} {}", l, o, r)) - .collect::>() - .join(", ") + Fmt::comma_separated(v.iter().map(|args| Fmt::new(args, |(l, o, r), f| write!( + f, + "{} {} {}", + l, o, r + )))) ), } } diff --git a/lib/src/sql/datetime.rs b/lib/src/sql/datetime.rs index 724802e4..d2eca9bb 100644 --- a/lib/src/sql/datetime.rs +++ b/lib/src/sql/datetime.rs @@ -20,19 +20,19 @@ pub struct Datetime(pub DateTime); impl Default for Datetime { fn default() -> Self { - Datetime(Utc::now()) + Self(Utc::now()) } } impl From for Datetime { fn from(v: i64) -> Self { - Datetime(Utc.timestamp(v, 0)) + Self(Utc.timestamp(v, 0)) } } impl From> for Datetime { fn from(v: DateTime) -> Self { - Datetime(v) + Self(v) } } @@ -40,7 +40,7 @@ impl From<&str> for Datetime { fn from(s: &str) -> Self { match datetime_raw(s) { Ok((_, v)) => v, - Err(_) => Datetime::default(), + Err(_) => Self::default(), } } } @@ -71,9 +71,9 @@ impl Serialize for Datetime { } } -impl ops::Sub for Datetime { +impl ops::Sub for Datetime { type Output = Duration; - fn sub(self, other: Datetime) -> Duration { + fn sub(self, other: Self) -> Duration { match (self.0 - other.0).to_std() { Ok(d) => Duration::from(d), Err(_) => Duration::default(), diff --git a/lib/src/sql/dir.rs b/lib/src/sql/dir.rs index 67758ff9..a15e9fe6 100644 --- a/lib/src/sql/dir.rs +++ b/lib/src/sql/dir.rs @@ -12,17 +12,17 @@ pub enum Dir { } impl Default for Dir { - fn default() -> Dir { - Dir::Both + fn default() -> Self { + Self::Both } } impl fmt::Display for Dir { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match self { - Dir::In => "<-", - Dir::Out => "->", - Dir::Both => "<->", + Self::In => "<-", + Self::Out => "->", + Self::Both => "<->", }) } } diff --git a/lib/src/sql/duration.rs b/lib/src/sql/duration.rs index 6b5f4be1..9d1aa87e 100644 --- a/lib/src/sql/duration.rs +++ b/lib/src/sql/duration.rs @@ -25,7 +25,7 @@ pub struct Duration(pub time::Duration); impl From for Duration { fn from(v: time::Duration) -> Self { - Duration(v) + Self(v) } } @@ -39,7 +39,7 @@ impl From<&str> for Duration { fn from(s: &str) -> Self { match duration(s) { Ok((_, v)) => v, - Err(_) => Duration::default(), + Err(_) => Self::default(), } } } diff --git a/lib/src/sql/error.rs b/lib/src/sql/error.rs index 508a5ff2..69bb902e 100644 --- a/lib/src/sql/error.rs +++ b/lib/src/sql/error.rs @@ -12,7 +12,7 @@ pub type IResult> = Result<(I, O), Err>; impl ParseError for Error { fn from_error_kind(input: I, _: ErrorKind) -> Self { - Error::ParserError(input) + Self::ParserError(input) } fn append(_: I, _: ErrorKind, other: Self) -> Self { other diff --git a/lib/src/sql/expression.rs b/lib/src/sql/expression.rs index 7bb75104..cfde7744 100644 --- a/lib/src/sql/expression.rs +++ b/lib/src/sql/expression.rs @@ -29,15 +29,15 @@ impl Default for Expression { impl Expression { // Create a new expression - fn new(l: Value, o: Operator, r: Value) -> Expression { - Expression { + fn new(l: Value, o: Operator, r: Value) -> Self { + Self { l, o, r, } } // Augment an existing expression - fn augment(mut self, l: Value, o: Operator) -> Expression { + fn augment(mut self, l: Value, o: Operator) -> Self { if o.precedence() >= self.o.precedence() { match self.l { Value::Expression(x) => { @@ -45,13 +45,13 @@ impl Expression { self } _ => { - self.l = Expression::new(l, o, self.l).into(); + self.l = Self::new(l, o, self.l).into(); self } } } else { let r = Value::from(self); - Expression::new(l, o, r) + Self::new(l, o, r) } } } diff --git a/lib/src/sql/fetch.rs b/lib/src/sql/fetch.rs index 65ab912f..1ac70a7d 100644 --- a/lib/src/sql/fetch.rs +++ b/lib/src/sql/fetch.rs @@ -1,11 +1,12 @@ use crate::sql::comment::shouldbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::idiom::{idiom, Idiom}; use nom::bytes::complete::tag_no_case; use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] @@ -28,11 +29,7 @@ impl IntoIterator for Fetchs { impl fmt::Display for Fetchs { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "FETCH {}", - self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ") - ) + write!(f, "FETCH {}", Fmt::comma_separated(&self.0)) } } @@ -46,9 +43,9 @@ impl Deref for Fetch { } } -impl fmt::Display for Fetch { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) +impl Display for Fetch { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) } } diff --git a/lib/src/sql/field.rs b/lib/src/sql/field.rs index 4b300673..7520afc5 100644 --- a/lib/src/sql/field.rs +++ b/lib/src/sql/field.rs @@ -5,6 +5,7 @@ use crate::err::Error; use crate::sql::comment::shouldbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::idiom::{idiom, Idiom}; use crate::sql::part::Part; use crate::sql::value::{value, Value}; @@ -12,7 +13,7 @@ use nom::branch::alt; use nom::bytes::complete::tag_no_case; use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter, Write}; use std::ops::Deref; #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] @@ -53,9 +54,9 @@ impl IntoIterator for Fields { } } -impl fmt::Display for Fields { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ")) +impl Display for Fields { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&Fmt::comma_separated(&self.0), f) } } @@ -198,17 +199,17 @@ pub enum Field { } impl Default for Field { - fn default() -> Field { - Field::All + fn default() -> Self { + Self::All } } -impl fmt::Display for Field { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Field { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Field::All => write!(f, "*"), - Field::Alone(e) => write!(f, "{}", e), - Field::Alias(e, a) => write!(f, "{} AS {}", e, a), + Self::All => f.write_char('*'), + Self::Alone(e) => Display::fmt(e, f), + Self::Alias(e, a) => write!(f, "{} AS {}", e, a), } } } diff --git a/lib/src/sql/fmt.rs b/lib/src/sql/fmt.rs new file mode 100644 index 00000000..fddeed9f --- /dev/null +++ b/lib/src/sql/fmt.rs @@ -0,0 +1,45 @@ +use std::cell::Cell; +use std::fmt::{self, Display, Formatter}; + +/// Implements fmt::Display by calling formatter on contents. +pub(crate) struct Fmt { + contents: Cell>, + formatter: F, +} + +impl fmt::Result> Fmt { + pub(crate) fn new(t: T, formatter: F) -> Self { + Self { + contents: Cell::new(Some(t)), + formatter, + } + } +} + +impl fmt::Result> Display for Fmt { + /// fmt is single-use only. + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let contents = self.contents.replace(None).expect("only call Fmt::fmt once"); + (self.formatter)(contents, f) + } +} + +impl, T: Display> Fmt fmt::Result> { + /// Formats values with a comma and a space separating them. + pub(crate) fn comma_separated(into_iter: I) -> Self { + Self::new(into_iter, fmt_comma_separated) + } +} + +fn fmt_comma_separated( + into_iter: impl IntoIterator, + f: &mut Formatter, +) -> fmt::Result { + for (i, v) in into_iter.into_iter().enumerate() { + if i > 0 { + f.write_str(", ")?; + } + Display::fmt(&v, f)?; + } + Ok(()) +} diff --git a/lib/src/sql/function.rs b/lib/src/sql/function.rs index 25292455..e4a6a9dd 100644 --- a/lib/src/sql/function.rs +++ b/lib/src/sql/function.rs @@ -6,6 +6,7 @@ use crate::fnc; use crate::sql::comment::mightbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::script::{script as func, Script}; use crate::sql::value::{single, value, Value}; use nom::branch::alt; @@ -35,21 +36,21 @@ impl Function { // Get function name if applicable pub fn name(&self) -> &str { match self { - Function::Normal(n, _) => n.as_str(), + Self::Normal(n, _) => n.as_str(), _ => unreachable!(), } } // Get function arguments if applicable pub fn args(&self) -> &[Value] { match self { - Function::Normal(_, a) => a, + Self::Normal(_, a) => a, _ => &[], } } // Convert this function to an aggregate - pub fn aggregate(&self, val: Value) -> Function { + pub fn aggregate(&self, val: Value) -> Self { match self { - Function::Normal(n, a) => { + Self::Normal(n, a) => { let mut a = a.to_owned(); match a.len() { 0 => a.insert(0, val), @@ -58,7 +59,7 @@ impl Function { a.insert(0, val); } } - Function::Normal(n.to_owned(), a) + Self::Normal(n.to_owned(), a) } _ => unreachable!(), } @@ -66,38 +67,38 @@ impl Function { // Check if this function is a rolling function pub fn is_rolling(&self) -> bool { match self { - Function::Normal(f, _) if f == "count" => true, - Function::Normal(f, _) if f == "math::max" => true, - Function::Normal(f, _) if f == "math::mean" => true, - Function::Normal(f, _) if f == "math::min" => true, - Function::Normal(f, _) if f == "math::sum" => true, + Self::Normal(f, _) if f == "count" => true, + Self::Normal(f, _) if f == "math::max" => true, + Self::Normal(f, _) if f == "math::mean" => true, + Self::Normal(f, _) if f == "math::min" => true, + Self::Normal(f, _) if f == "math::sum" => true, _ => false, } } // Check if this function is a grouping function pub fn is_aggregate(&self) -> bool { match self { - Function::Normal(f, _) if f == "array::concat" => true, - Function::Normal(f, _) if f == "array::distinct" => true, - Function::Normal(f, _) if f == "array::union" => true, - Function::Normal(f, _) if f == "count" => true, - Function::Normal(f, _) if f == "math::bottom" => true, - Function::Normal(f, _) if f == "math::interquartile" => true, - Function::Normal(f, _) if f == "math::max" => true, - Function::Normal(f, _) if f == "math::mean" => true, - Function::Normal(f, _) if f == "math::median" => true, - Function::Normal(f, _) if f == "math::midhinge" => true, - Function::Normal(f, _) if f == "math::min" => true, - Function::Normal(f, _) if f == "math::mode" => true, - Function::Normal(f, _) if f == "math::nearestrank" => true, - Function::Normal(f, _) if f == "math::percentile" => true, - Function::Normal(f, _) if f == "math::sample" => true, - Function::Normal(f, _) if f == "math::spread" => true, - Function::Normal(f, _) if f == "math::stddev" => true, - Function::Normal(f, _) if f == "math::sum" => true, - Function::Normal(f, _) if f == "math::top" => true, - Function::Normal(f, _) if f == "math::trimean" => true, - Function::Normal(f, _) if f == "math::variance" => true, + Self::Normal(f, _) if f == "array::concat" => true, + Self::Normal(f, _) if f == "array::distinct" => true, + Self::Normal(f, _) if f == "array::union" => true, + Self::Normal(f, _) if f == "count" => true, + Self::Normal(f, _) if f == "math::bottom" => true, + Self::Normal(f, _) if f == "math::interquartile" => true, + Self::Normal(f, _) if f == "math::max" => true, + Self::Normal(f, _) if f == "math::mean" => true, + Self::Normal(f, _) if f == "math::median" => true, + Self::Normal(f, _) if f == "math::midhinge" => true, + Self::Normal(f, _) if f == "math::min" => true, + Self::Normal(f, _) if f == "math::mode" => true, + Self::Normal(f, _) if f == "math::nearestrank" => true, + Self::Normal(f, _) if f == "math::percentile" => true, + Self::Normal(f, _) if f == "math::sample" => true, + Self::Normal(f, _) if f == "math::spread" => true, + Self::Normal(f, _) if f == "math::stddev" => true, + Self::Normal(f, _) if f == "math::sum" => true, + Self::Normal(f, _) if f == "math::top" => true, + Self::Normal(f, _) if f == "math::trimean" => true, + Self::Normal(f, _) if f == "math::variance" => true, _ => false, } } @@ -112,18 +113,18 @@ impl Function { doc: Option<&Value>, ) -> Result { match self { - Function::Future(v) => match opt.futures { + Self::Future(v) => match opt.futures { true => { let v = v.compute(ctx, opt, txn, doc).await?; fnc::future::run(ctx, v) } false => Ok(self.to_owned().into()), }, - Function::Cast(s, x) => { + Self::Cast(s, x) => { let v = x.compute(ctx, opt, txn, doc).await?; fnc::cast::run(ctx, s, v) } - Function::Normal(s, x) => { + Self::Normal(s, x) => { let mut a: Vec = Vec::with_capacity(x.len()); for v in x { a.push(v.compute(ctx, opt, txn, doc).await?); @@ -131,7 +132,7 @@ impl Function { fnc::run(ctx, s, a).await } #[allow(unused_variables)] - Function::Script(s, x) => { + Self::Script(s, x) => { #[cfg(feature = "scripting")] { let mut a: Vec = Vec::with_capacity(x.len()); @@ -154,20 +155,12 @@ impl Function { impl fmt::Display for Function { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Function::Future(ref e) => write!(f, " {{ {} }}", e), - Function::Cast(ref s, ref e) => write!(f, "<{}> {}", s, e), - Function::Script(ref s, ref e) => write!( - f, - "function({}) {{{}}}", - e.iter().map(|ref v| format!("{}", v)).collect::>().join(", "), - s, - ), - Function::Normal(ref s, ref e) => write!( - f, - "{}({})", - s, - e.iter().map(|ref v| format!("{}", v)).collect::>().join(", ") - ), + Self::Future(ref e) => write!(f, " {{ {} }}", e), + Self::Cast(ref s, ref e) => write!(f, "<{}> {}", s, e), + Self::Script(ref s, ref e) => { + write!(f, "function({}) {{{}}}", Fmt::comma_separated(e), s) + } + Self::Normal(ref s, ref e) => write!(f, "{}({})", s, Fmt::comma_separated(e)), } } } diff --git a/lib/src/sql/geometry.rs b/lib/src/sql/geometry.rs index 7646d322..78111bf1 100644 --- a/lib/src/sql/geometry.rs +++ b/lib/src/sql/geometry.rs @@ -1,6 +1,7 @@ use crate::sql::comment::mightbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::serde::is_internal_serialization; use geo::algorithm::contains::Contains; use geo::algorithm::intersects::Intersects; @@ -43,73 +44,73 @@ impl PartialOrd for Geometry { impl From<(f64, f64)> for Geometry { fn from(v: (f64, f64)) -> Self { - Geometry::Point(v.into()) + Self::Point(v.into()) } } impl From<[f64; 2]> for Geometry { fn from(v: [f64; 2]) -> Self { - Geometry::Point(v.into()) + Self::Point(v.into()) } } impl From> for Geometry { fn from(v: Point) -> Self { - Geometry::Point(v) + Self::Point(v) } } impl From> for Geometry { fn from(v: LineString) -> Self { - Geometry::Line(v) + Self::Line(v) } } impl From> for Geometry { fn from(v: Polygon) -> Self { - Geometry::Polygon(v) + Self::Polygon(v) } } impl From> for Geometry { fn from(v: MultiPoint) -> Self { - Geometry::MultiPoint(v) + Self::MultiPoint(v) } } impl From> for Geometry { fn from(v: MultiLineString) -> Self { - Geometry::MultiLine(v) + Self::MultiLine(v) } } impl From> for Geometry { fn from(v: MultiPolygon) -> Self { - Geometry::MultiPolygon(v) + Self::MultiPolygon(v) } } impl From> for Geometry { fn from(v: Vec) -> Self { - Geometry::Collection(v) + Self::Collection(v) } } impl From>> for Geometry { fn from(v: Vec>) -> Self { - Geometry::MultiPoint(MultiPoint(v)) + Self::MultiPoint(MultiPoint(v)) } } impl From>> for Geometry { fn from(v: Vec>) -> Self { - Geometry::MultiLine(MultiLineString(v)) + Self::MultiLine(MultiLineString(v)) } } impl From>> for Geometry { fn from(v: Vec>) -> Self { - Geometry::MultiPolygon(MultiPolygon(v)) + Self::MultiPolygon(MultiPolygon(v)) } } @@ -142,112 +143,112 @@ impl Geometry { // Value operations // ----------------------------------- - pub fn contains(&self, other: &Geometry) -> bool { + pub fn contains(&self, other: &Self) -> bool { match self { - Geometry::Point(v) => match other { - Geometry::Point(w) => v.contains(w), - Geometry::MultiPoint(w) => w.iter().all(|x| v.contains(x)), - Geometry::Collection(w) => w.iter().all(|x| self.contains(x)), + Self::Point(v) => match other { + Self::Point(w) => v.contains(w), + Self::MultiPoint(w) => w.iter().all(|x| v.contains(x)), + Self::Collection(w) => w.iter().all(|x| self.contains(x)), _ => false, }, - Geometry::Line(v) => match other { - Geometry::Point(w) => v.contains(w), - Geometry::Line(w) => v.contains(w), - Geometry::MultiLine(w) => w.iter().all(|x| w.contains(x)), - Geometry::Collection(w) => w.iter().all(|x| self.contains(x)), + Self::Line(v) => match other { + Self::Point(w) => v.contains(w), + Self::Line(w) => v.contains(w), + Self::MultiLine(w) => w.iter().all(|x| w.contains(x)), + Self::Collection(w) => w.iter().all(|x| self.contains(x)), _ => false, }, - Geometry::Polygon(v) => match other { - Geometry::Point(w) => v.contains(w), - Geometry::Line(w) => v.contains(w), - Geometry::Polygon(w) => v.contains(w), - Geometry::MultiPolygon(w) => w.iter().all(|x| w.contains(x)), - Geometry::Collection(w) => w.iter().all(|x| self.contains(x)), + Self::Polygon(v) => match other { + Self::Point(w) => v.contains(w), + Self::Line(w) => v.contains(w), + Self::Polygon(w) => v.contains(w), + Self::MultiPolygon(w) => w.iter().all(|x| w.contains(x)), + Self::Collection(w) => w.iter().all(|x| self.contains(x)), _ => false, }, - Geometry::MultiPoint(v) => match other { - Geometry::Point(w) => v.contains(w), - Geometry::MultiPoint(w) => w.iter().all(|x| w.contains(x)), - Geometry::Collection(w) => w.iter().all(|x| self.contains(x)), + Self::MultiPoint(v) => match other { + Self::Point(w) => v.contains(w), + Self::MultiPoint(w) => w.iter().all(|x| w.contains(x)), + Self::Collection(w) => w.iter().all(|x| self.contains(x)), _ => false, }, - Geometry::MultiLine(v) => match other { - Geometry::Point(w) => v.contains(w), - Geometry::Line(w) => v.contains(w), - Geometry::MultiLine(w) => w.iter().all(|x| w.contains(x)), - Geometry::Collection(w) => w.iter().all(|x| self.contains(x)), + Self::MultiLine(v) => match other { + Self::Point(w) => v.contains(w), + Self::Line(w) => v.contains(w), + Self::MultiLine(w) => w.iter().all(|x| w.contains(x)), + Self::Collection(w) => w.iter().all(|x| self.contains(x)), _ => false, }, - Geometry::MultiPolygon(v) => match other { - Geometry::Point(w) => v.contains(w), - Geometry::Line(w) => v.contains(w), - Geometry::Polygon(w) => v.contains(w), - Geometry::MultiPoint(w) => v.contains(w), - Geometry::MultiLine(w) => v.contains(w), - Geometry::MultiPolygon(w) => v.contains(w), - Geometry::Collection(w) => w.iter().all(|x| self.contains(x)), + Self::MultiPolygon(v) => match other { + Self::Point(w) => v.contains(w), + Self::Line(w) => v.contains(w), + Self::Polygon(w) => v.contains(w), + Self::MultiPoint(w) => v.contains(w), + Self::MultiLine(w) => v.contains(w), + Self::MultiPolygon(w) => v.contains(w), + Self::Collection(w) => w.iter().all(|x| self.contains(x)), }, - Geometry::Collection(v) => v.iter().all(|x| x.contains(other)), + Self::Collection(v) => v.iter().all(|x| x.contains(other)), } } - pub fn intersects(&self, other: &Geometry) -> bool { + pub fn intersects(&self, other: &Self) -> bool { match self { - Geometry::Point(v) => match other { - Geometry::Point(w) => v.intersects(w), - Geometry::Line(w) => v.intersects(w), - Geometry::Polygon(w) => v.intersects(w), - Geometry::MultiPoint(w) => v.intersects(w), - Geometry::MultiLine(w) => w.iter().any(|x| v.intersects(x)), - Geometry::MultiPolygon(w) => v.intersects(w), - Geometry::Collection(w) => w.iter().all(|x| self.intersects(x)), + Self::Point(v) => match other { + Self::Point(w) => v.intersects(w), + Self::Line(w) => v.intersects(w), + Self::Polygon(w) => v.intersects(w), + Self::MultiPoint(w) => v.intersects(w), + Self::MultiLine(w) => w.iter().any(|x| v.intersects(x)), + Self::MultiPolygon(w) => v.intersects(w), + Self::Collection(w) => w.iter().all(|x| self.intersects(x)), }, - Geometry::Line(v) => match other { - Geometry::Point(w) => v.intersects(w), - Geometry::Line(w) => v.intersects(w), - Geometry::Polygon(w) => v.intersects(w), - Geometry::MultiPoint(w) => v.intersects(w), - Geometry::MultiLine(w) => w.iter().any(|x| v.intersects(x)), - Geometry::MultiPolygon(w) => v.intersects(w), - Geometry::Collection(w) => w.iter().all(|x| self.intersects(x)), + Self::Line(v) => match other { + Self::Point(w) => v.intersects(w), + Self::Line(w) => v.intersects(w), + Self::Polygon(w) => v.intersects(w), + Self::MultiPoint(w) => v.intersects(w), + Self::MultiLine(w) => w.iter().any(|x| v.intersects(x)), + Self::MultiPolygon(w) => v.intersects(w), + Self::Collection(w) => w.iter().all(|x| self.intersects(x)), }, - Geometry::Polygon(v) => match other { - Geometry::Point(w) => v.intersects(w), - Geometry::Line(w) => v.intersects(w), - Geometry::Polygon(w) => v.intersects(w), - Geometry::MultiPoint(w) => v.intersects(w), - Geometry::MultiLine(w) => v.intersects(w), - Geometry::MultiPolygon(w) => v.intersects(w), - Geometry::Collection(w) => w.iter().all(|x| self.intersects(x)), + Self::Polygon(v) => match other { + Self::Point(w) => v.intersects(w), + Self::Line(w) => v.intersects(w), + Self::Polygon(w) => v.intersects(w), + Self::MultiPoint(w) => v.intersects(w), + Self::MultiLine(w) => v.intersects(w), + Self::MultiPolygon(w) => v.intersects(w), + Self::Collection(w) => w.iter().all(|x| self.intersects(x)), }, - Geometry::MultiPoint(v) => match other { - Geometry::Point(w) => v.intersects(w), - Geometry::Line(w) => v.intersects(w), - Geometry::Polygon(w) => v.intersects(w), - Geometry::MultiPoint(w) => v.intersects(w), - Geometry::MultiLine(w) => w.iter().any(|x| v.intersects(x)), - Geometry::MultiPolygon(w) => v.intersects(w), - Geometry::Collection(w) => w.iter().all(|x| self.intersects(x)), + Self::MultiPoint(v) => match other { + Self::Point(w) => v.intersects(w), + Self::Line(w) => v.intersects(w), + Self::Polygon(w) => v.intersects(w), + Self::MultiPoint(w) => v.intersects(w), + Self::MultiLine(w) => w.iter().any(|x| v.intersects(x)), + Self::MultiPolygon(w) => v.intersects(w), + Self::Collection(w) => w.iter().all(|x| self.intersects(x)), }, - Geometry::MultiLine(v) => match other { - Geometry::Point(w) => v.intersects(w), - Geometry::Line(w) => v.intersects(w), - Geometry::Polygon(w) => v.intersects(w), - Geometry::MultiPoint(w) => v.intersects(w), - Geometry::MultiLine(w) => w.iter().any(|x| v.intersects(x)), - Geometry::MultiPolygon(w) => v.intersects(w), - Geometry::Collection(w) => w.iter().all(|x| self.intersects(x)), + Self::MultiLine(v) => match other { + Self::Point(w) => v.intersects(w), + Self::Line(w) => v.intersects(w), + Self::Polygon(w) => v.intersects(w), + Self::MultiPoint(w) => v.intersects(w), + Self::MultiLine(w) => w.iter().any(|x| v.intersects(x)), + Self::MultiPolygon(w) => v.intersects(w), + Self::Collection(w) => w.iter().all(|x| self.intersects(x)), }, - Geometry::MultiPolygon(v) => match other { - Geometry::Point(w) => v.intersects(w), - Geometry::Line(w) => v.intersects(w), - Geometry::Polygon(w) => v.intersects(w), - Geometry::MultiPoint(w) => v.intersects(w), - Geometry::MultiLine(w) => v.intersects(w), - Geometry::MultiPolygon(w) => v.intersects(w), - Geometry::Collection(w) => w.iter().all(|x| self.intersects(x)), + Self::MultiPolygon(v) => match other { + Self::Point(w) => v.intersects(w), + Self::Line(w) => v.intersects(w), + Self::Polygon(w) => v.intersects(w), + Self::MultiPoint(w) => v.intersects(w), + Self::MultiLine(w) => v.intersects(w), + Self::MultiPolygon(w) => v.intersects(w), + Self::Collection(w) => w.iter().all(|x| self.intersects(x)), }, - Geometry::Collection(v) => v.iter().all(|x| x.intersects(other)), + Self::Collection(v) => v.iter().all(|x| x.intersects(other)), } } } @@ -255,108 +256,119 @@ impl Geometry { impl fmt::Display for Geometry { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Geometry::Point(v) => { + Self::Point(v) => { write!(f, "({}, {})", v.x(), v.y()) } - Geometry::Line(v) => write!( + Self::Line(v) => write!( f, "{{ type: 'LineString', coordinates: [{}] }}", - v.points() - .map(|ref v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", ") + Fmt::comma_separated(v.points().map(|v| Fmt::new(v, |v, f| write!( + f, + "[{}, {}]", + v.x(), + v.y() + )))) ), - Geometry::Polygon(v) => write!( + Self::Polygon(v) => write!( f, "{{ type: 'Polygon', coordinates: [[{}]{}] }}", - v.exterior() - .points() - .map(|ref v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", "), - match v.interiors().len() { - 0 => String::new(), - _ => format!( - ", [{}]", - v.interiors() - .iter() - .map(|i| { - format!( + Fmt::comma_separated(v.exterior().points().map(|v| Fmt::new(v, |v, f| write!( + f, + "[{}, {}]", + v.x(), + v.y() + )))), + Fmt::new(v.interiors(), |interiors, f| { + match interiors.len() { + 0 => Ok(()), + _ => write!( + f, + ", [{}]", + Fmt::comma_separated(interiors.iter().map(|i| Fmt::new(i, |i, f| { + write!( + f, "[{}]", - i.points() - .map(|ref v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", ") + Fmt::comma_separated(i.points().map(|v| Fmt::new( + v, + |v, f| write!(f, "[{}, {}]", v.x(), v.y()) + ))) ) - }) - .collect::>() - .join(", "), - ), - } + }))) + ), + } + }) ), - Geometry::MultiPoint(v) => { + Self::MultiPoint(v) => { write!( f, "{{ type: 'MultiPoint', coordinates: [{}] }}", - v.iter() - .map(|v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", ") + Fmt::comma_separated(v.iter().map(|v| Fmt::new(v, |v, f| write!( + f, + "[{}, {}]", + v.x(), + v.y() + )))) ) } - Geometry::MultiLine(v) => write!( + Self::MultiLine(v) => write!( f, "{{ type: 'MultiLineString', coordinates: [{}] }}", - v.iter() - .map(|v| format!( - "[{}]", - v.points() - .map(|ref v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", ") - )) - .collect::>() - .join(", ") + Fmt::comma_separated(v.iter().map(|v| Fmt::new(v, |v, f| write!( + f, + "[{}]", + Fmt::comma_separated(v.points().map(|v| Fmt::new(v, |v, f| write!( + f, + "[{}, {}]", + v.x(), + v.y() + )))) + )))) ), - Geometry::MultiPolygon(v) => write!( + Self::MultiPolygon(v) => write!( f, "{{ type: 'MultiPolygon', coordinates: [{}] }}", - v.iter() - .map(|v| format!( + Fmt::comma_separated(v.iter().map(|v| Fmt::new(v, |v, f| { + write!( + f, "[[{}]{}]", - v.exterior() - .points() - .map(|ref v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", "), - match v.interiors().len() { - 0 => String::new(), - _ => format!( - ", [{}]", - v.interiors() - .iter() - .map(|i| { - format!( - "[{}]", - i.points() - .map(|ref v| format!("[{}, {}]", v.x(), v.y())) - .collect::>() - .join(", ") - ) - }) - .collect::>() - .join(", "), - ), - } - )) - .collect::>() - .join(", "), + Fmt::comma_separated( + v.exterior().points().map(|v| Fmt::new(v, |v, f| write!( + f, + "[{}, {}]", + v.x(), + v.y() + ))) + ), + Fmt::new(v.interiors(), |interiors, f| { + match interiors.len() { + 0 => Ok(()), + _ => write!( + f, + ", [{}]", + Fmt::comma_separated(interiors.iter().map(|i| Fmt::new( + i, + |i, f| { + write!( + f, + "[{}]", + Fmt::comma_separated(i.points().map(|v| Fmt::new( + v, + |v, f| write!(f, "[{}, {}]", v.x(), v.y()) + ))) + ) + } + ))) + ), + } + }) + ) + }))), ), - Geometry::Collection(v) => { + Self::Collection(v) => { write!( f, "{{ type: 'GeometryCollection', geometries: [{}] }}", - v.iter().map(|v| format!("{}", v)).collect::>().join(", ") + Fmt::comma_separated(v) ) } } @@ -370,25 +382,19 @@ impl Serialize for Geometry { { if is_internal_serialization() { match self { - Geometry::Point(v) => s.serialize_newtype_variant("Geometry", 0, "Point", v), - Geometry::Line(v) => s.serialize_newtype_variant("Geometry", 1, "Line", v), - Geometry::Polygon(v) => s.serialize_newtype_variant("Geometry", 2, "Polygon", v), - Geometry::MultiPoint(v) => { - s.serialize_newtype_variant("Geometry", 3, "MultiPoint", v) - } - Geometry::MultiLine(v) => { - s.serialize_newtype_variant("Geometry", 4, "MultiLine", v) - } - Geometry::MultiPolygon(v) => { + Self::Point(v) => s.serialize_newtype_variant("Geometry", 0, "Point", v), + Self::Line(v) => s.serialize_newtype_variant("Geometry", 1, "Line", v), + Self::Polygon(v) => s.serialize_newtype_variant("Geometry", 2, "Polygon", v), + Self::MultiPoint(v) => s.serialize_newtype_variant("Geometry", 3, "MultiPoint", v), + Self::MultiLine(v) => s.serialize_newtype_variant("Geometry", 4, "MultiLine", v), + Self::MultiPolygon(v) => { s.serialize_newtype_variant("Geometry", 5, "MultiPolygon", v) } - Geometry::Collection(v) => { - s.serialize_newtype_variant("Geometry", 6, "Collection", v) - } + Self::Collection(v) => s.serialize_newtype_variant("Geometry", 6, "Collection", v), } } else { match self { - Geometry::Point(v) => { + Self::Point(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("Point")?; @@ -396,7 +402,7 @@ impl Serialize for Geometry { map.serialize_value(vec![v.x(), v.y()].as_slice())?; map.end() } - Geometry::Line(v) => { + Self::Line(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("LineString")?; @@ -409,7 +415,7 @@ impl Serialize for Geometry { )?; map.end() } - Geometry::Polygon(v) => { + Self::Polygon(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("Polygon")?; @@ -436,7 +442,7 @@ impl Serialize for Geometry { )?; map.end() } - Geometry::MultiPoint(v) => { + Self::MultiPoint(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("MultiPoint")?; @@ -449,7 +455,7 @@ impl Serialize for Geometry { )?; map.end() } - Geometry::MultiLine(v) => { + Self::MultiLine(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("MultiLineString")?; @@ -464,7 +470,7 @@ impl Serialize for Geometry { )?; map.end() } - Geometry::MultiPolygon(v) => { + Self::MultiPolygon(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("MultiPolygon")?; @@ -495,7 +501,7 @@ impl Serialize for Geometry { )?; map.end() } - Geometry::Collection(v) => { + Self::Collection(v) => { let mut map = s.serialize_map(Some(2))?; map.serialize_key("type")?; map.serialize_value("GeometryCollection")?; diff --git a/lib/src/sql/graph.rs b/lib/src/sql/graph.rs index f1498952..d8a3c6a4 100644 --- a/lib/src/sql/graph.rs +++ b/lib/src/sql/graph.rs @@ -11,7 +11,7 @@ use nom::character::complete::char; use nom::combinator::map; use nom::combinator::opt; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter, Write}; #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] pub struct Graph { @@ -27,19 +27,19 @@ impl Graph { } } -impl fmt::Display for Graph { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Graph { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { if self.what.0.len() <= 1 && self.cond.is_none() && self.alias.is_none() { - write!(f, "{}", self.dir)?; + Display::fmt(&self.dir, f)?; match self.what.len() { - 0 => write!(f, "?"), - _ => write!(f, "{}", self.what), + 0 => f.write_char('?'), + _ => Display::fmt(&self.what, f), } } else { write!(f, "{}(", self.dir)?; match self.what.len() { - 0 => write!(f, "?"), - _ => write!(f, "{}", self.what), + 0 => f.write_char('?'), + _ => Display::fmt(&self.what, f), }?; if let Some(ref v) = self.cond { write!(f, " {}", v)? @@ -47,7 +47,7 @@ impl fmt::Display for Graph { if let Some(ref v) = self.alias { write!(f, " AS {}", v)? } - write!(f, ")") + f.write_char(')') } } } diff --git a/lib/src/sql/group.rs b/lib/src/sql/group.rs index 464fc634..f9390beb 100644 --- a/lib/src/sql/group.rs +++ b/lib/src/sql/group.rs @@ -1,13 +1,14 @@ use crate::sql::comment::shouldbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::idiom::{basic, Idiom}; use nom::bytes::complete::tag_no_case; use nom::combinator::opt; use nom::multi::separated_list1; use nom::sequence::tuple; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] @@ -28,13 +29,9 @@ impl IntoIterator for Groups { } } -impl fmt::Display for Groups { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "GROUP BY {}", - self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ") - ) +impl Display for Groups { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "GROUP BY {}", Fmt::comma_separated(&self.0)) } } @@ -48,9 +45,9 @@ impl Deref for Group { } } -impl fmt::Display for Group { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) +impl Display for Group { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) } } diff --git a/lib/src/sql/id.rs b/lib/src/sql/id.rs index 5328b1f0..323750ff 100644 --- a/lib/src/sql/id.rs +++ b/lib/src/sql/id.rs @@ -12,7 +12,7 @@ use nanoid::nanoid; use nom::branch::alt; use nom::combinator::map; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum Id { @@ -24,55 +24,55 @@ pub enum Id { impl From for Id { fn from(v: i64) -> Self { - Id::Number(v) + Self::Number(v) } } impl From for Id { fn from(v: i32) -> Self { - Id::Number(v as i64) + Self::Number(v as i64) } } impl From for Id { fn from(v: u64) -> Self { - Id::Number(v as i64) + Self::Number(v as i64) } } impl From for Id { fn from(v: String) -> Self { - Id::String(v) + Self::String(v) } } impl From for Id { fn from(v: Array) -> Self { - Id::Array(v) + Self::Array(v) } } impl From for Id { fn from(v: Object) -> Self { - Id::Object(v) + Self::Object(v) } } impl From for Id { fn from(v: Uuid) -> Self { - Id::String(v.to_raw()) + Self::String(v.to_raw()) } } impl From for Id { fn from(v: Strand) -> Self { - Id::String(v.as_string()) + Self::String(v.as_string()) } } impl From<&str> for Id { fn from(v: &str) -> Self { - Id::String(v.to_owned()) + Self::String(v.to_owned()) } } @@ -83,26 +83,26 @@ impl From> for Id { } impl Id { - pub fn rand() -> Id { - Id::String(nanoid!(20, &ID_CHARS)) + pub fn rand() -> Self { + Self::String(nanoid!(20, &ID_CHARS)) } pub fn to_raw(&self) -> String { match self { - Id::Number(v) => v.to_string(), - Id::String(v) => v.to_string(), - Id::Object(v) => v.to_string(), - Id::Array(v) => v.to_string(), + Self::Number(v) => v.to_string(), + Self::String(v) => v.to_string(), + Self::Object(v) => v.to_string(), + Self::Array(v) => v.to_string(), } } } -impl fmt::Display for Id { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Id { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Id::Number(v) => write!(f, "{}", v), - Id::String(v) => write!(f, "{}", escape_id(v)), - Id::Object(v) => write!(f, "{}", v), - Id::Array(v) => write!(f, "{}", v), + Self::Number(v) => Display::fmt(v, f), + Self::String(v) => Display::fmt(&escape_id(v), f), + Self::Object(v) => Display::fmt(v, f), + Self::Array(v) => Display::fmt(v, f), } } } diff --git a/lib/src/sql/ident.rs b/lib/src/sql/ident.rs index 380ad3ad..a6b22d19 100644 --- a/lib/src/sql/ident.rs +++ b/lib/src/sql/ident.rs @@ -10,7 +10,7 @@ use nom::character::complete::char; use nom::character::complete::one_of; use nom::sequence::delimited; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; @@ -26,13 +26,13 @@ pub struct Ident(pub String); impl From for Ident { fn from(s: String) -> Self { - Ident(s) + Self(s) } } impl From<&str> for Ident { - fn from(i: &str) -> Ident { - Ident(String::from(i)) + fn from(i: &str) -> Self { + Self::from(String::from(i)) } } @@ -49,9 +49,9 @@ impl Ident { } } -impl fmt::Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", escape_ident(&self.0)) +impl Display for Ident { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&escape_ident(&self.0), f) } } diff --git a/lib/src/sql/idiom.rs b/lib/src/sql/idiom.rs index 3feb45ed..3f8604f7 100644 --- a/lib/src/sql/idiom.rs +++ b/lib/src/sql/idiom.rs @@ -4,6 +4,7 @@ use crate::dbs::Transaction; use crate::err::Error; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::part::Next; use crate::sql::part::{all, field, first, graph, index, last, part, thing, Part}; use crate::sql::paths::{ID, IN, OUT}; @@ -14,7 +15,7 @@ use nom::branch::alt; use nom::multi::separated_list1; use nom::multi::{many0, many1}; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; @@ -28,9 +29,9 @@ impl Deref for Idioms { } } -impl fmt::Display for Idioms { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ")) +impl Display for Idioms { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&Fmt::comma_separated(&self.0), f) } } @@ -51,13 +52,13 @@ impl Deref for Idiom { impl From for Idiom { fn from(v: String) -> Self { - Idiom(vec![Part::from(v)]) + Self(vec![Part::from(v)]) } } impl From> for Idiom { fn from(v: Vec) -> Self { - Idiom(v) + Self(v) } } diff --git a/lib/src/sql/kind.rs b/lib/src/sql/kind.rs index c3ba1182..361d1f8c 100644 --- a/lib/src/sql/kind.rs +++ b/lib/src/sql/kind.rs @@ -1,6 +1,7 @@ use crate::sql::comment::mightbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::table::{table, Table}; use nom::branch::alt; use nom::bytes::complete::tag; @@ -8,7 +9,7 @@ use nom::character::complete::char; use nom::combinator::map; use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum Kind { @@ -28,13 +29,13 @@ pub enum Kind { } impl Default for Kind { - fn default() -> Kind { - Kind::Any + fn default() -> Self { + Self::Any } } -impl fmt::Display for Kind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Kind { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Kind::Any => f.write_str("any"), Kind::Array => f.write_str("array"), @@ -47,16 +48,8 @@ impl fmt::Display for Kind { Kind::Number => f.write_str("number"), Kind::Object => f.write_str("object"), Kind::String => f.write_str("string"), - Kind::Record(v) => write!( - f, - "record({})", - v.iter().map(|ref v| v.to_string()).collect::>().join(", ") - ), - Kind::Geometry(v) => write!( - f, - "geometry({})", - v.iter().map(|ref v| v.to_string()).collect::>().join(", ") - ), + Kind::Record(v) => write!(f, "record({})", Fmt::comma_separated(v)), + Kind::Geometry(v) => write!(f, "geometry({})", Fmt::comma_separated(v)), } } } diff --git a/lib/src/sql/mod.rs b/lib/src/sql/mod.rs index 7dad6186..43663f05 100644 --- a/lib/src/sql/mod.rs +++ b/lib/src/sql/mod.rs @@ -16,6 +16,7 @@ pub(crate) mod escape; pub(crate) mod expression; pub(crate) mod fetch; pub(crate) mod field; +pub(crate) mod fmt; pub(crate) mod function; pub(crate) mod geometry; pub(crate) mod graph; diff --git a/lib/src/sql/number.rs b/lib/src/sql/number.rs index 5e21eb1e..6607f9fa 100644 --- a/lib/src/sql/number.rs +++ b/lib/src/sql/number.rs @@ -10,8 +10,7 @@ use nom::combinator::map; use nom::number::complete::recognize_float; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; -use std::fmt; -use std::fmt::Display; +use std::fmt::{self, Display, Formatter}; use std::iter::Product; use std::iter::Sum; use std::ops; @@ -26,102 +25,102 @@ pub enum Number { impl Default for Number { fn default() -> Self { - Number::Int(0) + Self::Int(0) } } impl From for Number { fn from(i: i8) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: i16) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: i32) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: i64) -> Self { - Number::Int(i) + Self::Int(i) } } impl From for Number { fn from(i: isize) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: u8) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: u16) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: u32) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: u64) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(i: usize) -> Self { - Number::Int(i as i64) + Self::Int(i as i64) } } impl From for Number { fn from(f: f32) -> Self { - Number::Float(f as f64) + Self::Float(f as f64) } } impl From for Number { fn from(f: f64) -> Self { - Number::Float(f as f64) + Self::Float(f as f64) } } impl From<&str> for Number { fn from(s: &str) -> Self { - Number::Decimal(BigDecimal::from_str(s).unwrap_or_default()) + Self::Decimal(BigDecimal::from_str(s).unwrap_or_default()) } } impl From for Number { fn from(s: String) -> Self { - Number::Decimal(BigDecimal::from_str(&s).unwrap_or_default()) + Self::from(s.as_str()) } } impl From for Number { fn from(v: BigDecimal) -> Self { - Number::Decimal(v) + Self::Decimal(v) } } -impl fmt::Display for Number { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Number { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { Number::Int(v) => Display::fmt(v, f), Number::Float(v) => Display::fmt(v, f), diff --git a/lib/src/sql/object.rs b/lib/src/sql/object.rs index 978c8dcb..ba6ecc74 100644 --- a/lib/src/sql/object.rs +++ b/lib/src/sql/object.rs @@ -6,6 +6,7 @@ use crate::sql::comment::mightbespace; use crate::sql::common::{commas, val_char}; use crate::sql::error::IResult; use crate::sql::escape::escape_key; +use crate::sql::fmt::Fmt; use crate::sql::operation::{Op, Operation}; use crate::sql::serde::is_internal_serialization; use crate::sql::thing::Thing; @@ -30,25 +31,25 @@ pub struct Object(pub BTreeMap); impl From> for Object { fn from(v: BTreeMap) -> Self { - Object(v) + Self(v) } } impl From> for Object { fn from(v: HashMap) -> Self { - Object(v.into_iter().collect()) + Self(v.into_iter().collect()) } } -impl From> for Object { - fn from(v: Option) -> Self { +impl From> for Object { + fn from(v: Option) -> Self { v.unwrap_or_default() } } impl From for Object { fn from(v: Operation) -> Self { - Object(map! { + Self(map! { String::from("op") => match v.op { Op::None => Value::from("none"), Op::Add => Value::from("add"), @@ -138,10 +139,11 @@ impl fmt::Display for Object { write!( f, "{{ {} }}", - self.iter() - .map(|(k, v)| format!("{}: {}", escape_key(k), v)) - .collect::>() - .join(", ") + Fmt::comma_separated( + self.0.iter().map(|args| Fmt::new(args, |(k, v), f| { + write!(f, "{}: {}", escape_key(k), v) + })) + ) ) } } diff --git a/lib/src/sql/operator.rs b/lib/src/sql/operator.rs index f1bef2cc..abe151b8 100644 --- a/lib/src/sql/operator.rs +++ b/lib/src/sql/operator.rs @@ -53,8 +53,8 @@ pub enum Operator { } impl Default for Operator { - fn default() -> Operator { - Operator::Equal + fn default() -> Self { + Self::Equal } } @@ -76,39 +76,39 @@ impl Operator { impl fmt::Display for Operator { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match self { - Operator::Or => "OR", - Operator::And => "AND", - Operator::Add => "+", - Operator::Sub => "-", - Operator::Mul => "*", - Operator::Div => "/", - Operator::Inc => "+=", - Operator::Dec => "-=", - Operator::Exact => "==", - Operator::Equal => "=", - Operator::NotEqual => "!=", - Operator::AllEqual => "*=", - Operator::AnyEqual => "?=", - Operator::Like => "~", - Operator::NotLike => "!~", - Operator::AllLike => "*~", - Operator::AnyLike => "?~", - Operator::LessThan => "<", - Operator::LessThanOrEqual => "<=", - Operator::MoreThan => ">", - Operator::MoreThanOrEqual => ">=", - Operator::Contain => "CONTAINS", - Operator::NotContain => "CONTAINSNOT", - Operator::ContainAll => "CONTAINSALL", - Operator::ContainAny => "CONTAINSANY", - Operator::ContainNone => "CONTAINSNONE", - Operator::Inside => "INSIDE", - Operator::NotInside => "NOTINSIDE", - Operator::AllInside => "ALLINSIDE", - Operator::AnyInside => "ANYINSIDE", - Operator::NoneInside => "NONEINSIDE", - Operator::Outside => "OUTSIDE", - Operator::Intersects => "INTERSECTS", + Self::Or => "OR", + Self::And => "AND", + Self::Add => "+", + Self::Sub => "-", + Self::Mul => "*", + Self::Div => "/", + Self::Inc => "+=", + Self::Dec => "-=", + Self::Exact => "==", + Self::Equal => "=", + Self::NotEqual => "!=", + Self::AllEqual => "*=", + Self::AnyEqual => "?=", + Self::Like => "~", + Self::NotLike => "!~", + Self::AllLike => "*~", + Self::AnyLike => "?~", + Self::LessThan => "<", + Self::LessThanOrEqual => "<=", + Self::MoreThan => ">", + Self::MoreThanOrEqual => ">=", + Self::Contain => "CONTAINS", + Self::NotContain => "CONTAINSNOT", + Self::ContainAll => "CONTAINSALL", + Self::ContainAny => "CONTAINSANY", + Self::ContainNone => "CONTAINSNONE", + Self::Inside => "INSIDE", + Self::NotInside => "NOTINSIDE", + Self::AllInside => "ALLINSIDE", + Self::AnyInside => "ANYINSIDE", + Self::NoneInside => "NONEINSIDE", + Self::Outside => "OUTSIDE", + Self::Intersects => "INTERSECTS", }) } } diff --git a/lib/src/sql/order.rs b/lib/src/sql/order.rs index a8aa0ed5..38f92a06 100644 --- a/lib/src/sql/order.rs +++ b/lib/src/sql/order.rs @@ -1,6 +1,7 @@ use crate::sql::comment::shouldbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::idiom::{basic, Idiom}; use nom::branch::alt; use nom::bytes::complete::tag_no_case; @@ -31,11 +32,7 @@ impl IntoIterator for Orders { impl fmt::Display for Orders { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "ORDER BY {}", - self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ") - ) + write!(f, "ORDER BY {}", Fmt::comma_separated(&self.0)) } } diff --git a/lib/src/sql/output.rs b/lib/src/sql/output.rs index 0a53194f..5dbe8d2a 100644 --- a/lib/src/sql/output.rs +++ b/lib/src/sql/output.rs @@ -5,7 +5,7 @@ use nom::branch::alt; use nom::bytes::complete::tag_no_case; use nom::combinator::map; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum Output { @@ -18,21 +18,21 @@ pub enum Output { } impl Default for Output { - fn default() -> Output { - Output::None + fn default() -> Self { + Self::None } } -impl fmt::Display for Output { +impl Display for Output { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("RETURN ")?; match self { - Output::None => f.write_str("NONE"), - Output::Null => f.write_str("NULL"), - Output::Diff => f.write_str("DIFF"), - Output::After => f.write_str("AFTER"), - Output::Before => f.write_str("BEFORE"), - Output::Fields(v) => write!(f, "{}", v), + Self::None => f.write_str("NONE"), + Self::Null => f.write_str("NULL"), + Self::Diff => f.write_str("DIFF"), + Self::After => f.write_str("AFTER"), + Self::Before => f.write_str("BEFORE"), + Self::Fields(v) => Display::fmt(v, f), } } } diff --git a/lib/src/sql/param.rs b/lib/src/sql/param.rs index b0e80103..6b601cb5 100644 --- a/lib/src/sql/param.rs +++ b/lib/src/sql/param.rs @@ -18,8 +18,8 @@ use std::str; pub struct Param(pub Idiom); impl From for Param { - fn from(p: Idiom) -> Param { - Param(p) + fn from(p: Idiom) -> Self { + Self(p) } } diff --git a/lib/src/sql/parser.rs b/lib/src/sql/parser.rs index 542cd7d1..91bfd6a8 100644 --- a/lib/src/sql/parser.rs +++ b/lib/src/sql/parser.rs @@ -40,6 +40,7 @@ fn parse_impl(input: &str, parser: impl Fn(&str) -> IResult<&str, O>) -> Resu } fn truncate(s: &str, l: usize) -> &str { + // TODO: use s.floor_char_boundary once https://github.com/rust-lang/rust/issues/93743 lands match s.char_indices().nth(l) { None => s, Some((i, _)) => &s[..i], @@ -49,8 +50,7 @@ fn truncate(s: &str, l: usize) -> &str { fn locate<'a>(input: &str, tried: &'a str) -> (&'a str, usize, usize) { let index = input.len() - tried.len(); let tried = truncate(tried, 100); - let lines = input.split('\n').collect::>(); - let lines = lines.iter().map(|l| l.len()).enumerate(); + let lines = input.split('\n').map(|l| l.len()).enumerate(); let (mut total, mut chars) = (0, 0); for (line, size) in lines { total += size + 1; diff --git a/lib/src/sql/part.rs b/lib/src/sql/part.rs index f3863c60..814b50e6 100644 --- a/lib/src/sql/part.rs +++ b/lib/src/sql/part.rs @@ -29,63 +29,63 @@ pub enum Part { impl From for Part { fn from(v: i32) -> Self { - Part::Index(v.into()) + Self::Index(v.into()) } } impl From for Part { fn from(v: isize) -> Self { - Part::Index(v.into()) + Self::Index(v.into()) } } impl From for Part { fn from(v: usize) -> Self { - Part::Index(v.into()) + Self::Index(v.into()) } } impl From for Part { fn from(v: Number) -> Self { - Part::Index(v) + Self::Index(v) } } impl From for Part { fn from(v: Ident) -> Self { - Part::Field(v) + Self::Field(v) } } impl From for Part { fn from(v: Value) -> Self { - Part::Where(v) + Self::Where(v) } } impl From for Part { fn from(v: Thing) -> Self { - Part::Thing(v) + Self::Thing(v) } } impl From for Part { fn from(v: Graph) -> Self { - Part::Graph(v) + Self::Graph(v) } } impl From for Part { fn from(v: String) -> Self { - Part::Field(Ident(v)) + Self::Field(Ident(v)) } } impl From<&str> for Part { fn from(v: &str) -> Self { match v.parse::() { - Ok(v) => Part::from(v), - _ => Part::from(v.to_owned()), + Ok(v) => Self::from(v), + _ => Self::from(v.to_owned()), } } } @@ -103,9 +103,9 @@ impl Part { impl fmt::Display for Part { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Part::All => write!(f, "[*]"), - Part::Last => write!(f, "[$]"), - Part::First => write!(f, "[0]"), + Part::All => f.write_str("[*]"), + Part::Last => f.write_str("[$]"), + Part::First => f.write_str("[0]"), Part::Field(v) => write!(f, ".{}", v), Part::Index(v) => write!(f, "[{}]", v), Part::Where(v) => write!(f, "[WHERE {}]", v), diff --git a/lib/src/sql/permission.rs b/lib/src/sql/permission.rs index c44142db..eda82969 100644 --- a/lib/src/sql/permission.rs +++ b/lib/src/sql/permission.rs @@ -140,16 +140,16 @@ pub enum Permission { impl Default for Permission { fn default() -> Self { - Permission::Full + Self::Full } } impl fmt::Display for Permission { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Permission::None => write!(f, "NONE"), - Permission::Full => write!(f, "FULL"), - Permission::Specific(ref v) => write!(f, "WHERE {}", v), + Self::None => f.write_str("NONE"), + Self::Full => f.write_str("FULL"), + Self::Specific(ref v) => write!(f, "WHERE {}", v), } } } diff --git a/lib/src/sql/query.rs b/lib/src/sql/query.rs index 0f9f2db7..7bb680be 100644 --- a/lib/src/sql/query.rs +++ b/lib/src/sql/query.rs @@ -3,7 +3,7 @@ use crate::sql::statement::{statements, Statement, Statements}; use derive::Store; use nom::combinator::all_consuming; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; @@ -17,9 +17,9 @@ impl Deref for Query { } } -impl fmt::Display for Query { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) +impl Display for Query { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) } } diff --git a/lib/src/sql/regex.rs b/lib/src/sql/regex.rs index ff7e6afa..4ea9347d 100644 --- a/lib/src/sql/regex.rs +++ b/lib/src/sql/regex.rs @@ -12,8 +12,8 @@ use std::str; pub struct Regex(String); impl From<&str> for Regex { - fn from(r: &str) -> Regex { - Regex(r.replace("\\/", "/")) + fn from(r: &str) -> Self { + Self(r.replace("\\/", "/")) } } diff --git a/lib/src/sql/script.rs b/lib/src/sql/script.rs index 452b7c6e..e929e723 100644 --- a/lib/src/sql/script.rs +++ b/lib/src/sql/script.rs @@ -7,7 +7,7 @@ use nom::character::complete::one_of; use nom::combinator::recognize; use nom::multi::many1; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; @@ -28,13 +28,13 @@ pub struct Script(pub String); impl From for Script { fn from(s: String) -> Self { - Script(s) + Self(s) } } impl From<&str> for Script { fn from(s: &str) -> Self { - Script(String::from(s)) + Self::from(String::from(s)) } } @@ -45,9 +45,9 @@ impl Deref for Script { } } -impl fmt::Display for Script { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) +impl Display for Script { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) } } diff --git a/lib/src/sql/split.rs b/lib/src/sql/split.rs index 28514483..d91d9f39 100644 --- a/lib/src/sql/split.rs +++ b/lib/src/sql/split.rs @@ -1,13 +1,14 @@ use crate::sql::comment::shouldbespace; use crate::sql::common::commas; use crate::sql::error::IResult; +use crate::sql::fmt::Fmt; use crate::sql::idiom::{basic, Idiom}; use nom::bytes::complete::tag_no_case; use nom::combinator::opt; use nom::multi::separated_list1; use nom::sequence::tuple; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] @@ -30,11 +31,7 @@ impl IntoIterator for Splits { impl fmt::Display for Splits { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "SPLIT ON {}", - self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ") - ) + write!(f, "SPLIT ON {}", Fmt::comma_separated(&self.0)) } } @@ -48,9 +45,9 @@ impl Deref for Split { } } -impl fmt::Display for Split { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) +impl Display for Split { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) } } diff --git a/lib/src/sql/statement.rs b/lib/src/sql/statement.rs index 0cdaf4a4..635ca2b3 100644 --- a/lib/src/sql/statement.rs +++ b/lib/src/sql/statement.rs @@ -31,7 +31,7 @@ use nom::multi::many0; use nom::multi::separated_list1; use nom::sequence::delimited; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::time::Duration; @@ -47,7 +47,10 @@ impl Deref for Statements { impl fmt::Display for Statements { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0.iter().map(|ref v| format!("{};", v)).collect::>().join("\n")) + Display::fmt( + &self.0.iter().map(|ref v| format!("{};", v)).collect::>().join("\n"), + f, + ) } } @@ -83,34 +86,34 @@ pub enum Statement { impl Statement { pub fn timeout(&self) -> Option { match self { - Statement::Select(v) => v.timeout.as_ref().map(|v| *v.0), - Statement::Create(v) => v.timeout.as_ref().map(|v| *v.0), - Statement::Update(v) => v.timeout.as_ref().map(|v| *v.0), - Statement::Relate(v) => v.timeout.as_ref().map(|v| *v.0), - Statement::Delete(v) => v.timeout.as_ref().map(|v| *v.0), - Statement::Insert(v) => v.timeout.as_ref().map(|v| *v.0), + Self::Select(v) => v.timeout.as_ref().map(|v| *v.0), + Self::Create(v) => v.timeout.as_ref().map(|v| *v.0), + Self::Update(v) => v.timeout.as_ref().map(|v| *v.0), + Self::Relate(v) => v.timeout.as_ref().map(|v| *v.0), + Self::Delete(v) => v.timeout.as_ref().map(|v| *v.0), + Self::Insert(v) => v.timeout.as_ref().map(|v| *v.0), _ => None, } } pub(crate) fn writeable(&self) -> bool { match self { - Statement::Use(_) => false, - Statement::Set(v) => v.writeable(), - Statement::Info(_) => false, - Statement::Live(_) => true, - Statement::Kill(_) => true, - Statement::Output(v) => v.writeable(), - Statement::Ifelse(v) => v.writeable(), - Statement::Select(v) => v.writeable(), - Statement::Create(v) => v.writeable(), - Statement::Update(v) => v.writeable(), - Statement::Relate(v) => v.writeable(), - Statement::Delete(v) => v.writeable(), - Statement::Insert(v) => v.writeable(), - Statement::Define(_) => true, - Statement::Remove(_) => true, - Statement::Option(_) => false, + Self::Use(_) => false, + Self::Set(v) => v.writeable(), + Self::Info(_) => false, + Self::Live(_) => true, + Self::Kill(_) => true, + Self::Output(v) => v.writeable(), + Self::Ifelse(v) => v.writeable(), + Self::Select(v) => v.writeable(), + Self::Create(v) => v.writeable(), + Self::Update(v) => v.writeable(), + Self::Relate(v) => v.writeable(), + Self::Delete(v) => v.writeable(), + Self::Insert(v) => v.writeable(), + Self::Define(_) => true, + Self::Remove(_) => true, + Self::Option(_) => false, _ => unreachable!(), } } @@ -123,47 +126,47 @@ impl Statement { doc: Option<&Value>, ) -> Result { match self { - Statement::Set(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Info(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Live(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Kill(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Output(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Ifelse(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Select(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Create(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Update(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Relate(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Delete(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Insert(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Define(v) => v.compute(ctx, opt, txn, doc).await, - Statement::Remove(v) => v.compute(ctx, opt, txn, doc).await, + Self::Set(v) => v.compute(ctx, opt, txn, doc).await, + Self::Info(v) => v.compute(ctx, opt, txn, doc).await, + Self::Live(v) => v.compute(ctx, opt, txn, doc).await, + Self::Kill(v) => v.compute(ctx, opt, txn, doc).await, + Self::Output(v) => v.compute(ctx, opt, txn, doc).await, + Self::Ifelse(v) => v.compute(ctx, opt, txn, doc).await, + Self::Select(v) => v.compute(ctx, opt, txn, doc).await, + Self::Create(v) => v.compute(ctx, opt, txn, doc).await, + Self::Update(v) => v.compute(ctx, opt, txn, doc).await, + Self::Relate(v) => v.compute(ctx, opt, txn, doc).await, + Self::Delete(v) => v.compute(ctx, opt, txn, doc).await, + Self::Insert(v) => v.compute(ctx, opt, txn, doc).await, + Self::Define(v) => v.compute(ctx, opt, txn, doc).await, + Self::Remove(v) => v.compute(ctx, opt, txn, doc).await, _ => unreachable!(), } } } -impl fmt::Display for Statement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Statement { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Statement::Use(v) => write!(f, "{}", v), - Statement::Set(v) => write!(f, "{}", v), - Statement::Info(v) => write!(f, "{}", v), - Statement::Live(v) => write!(f, "{}", v), - Statement::Kill(v) => write!(f, "{}", v), - Statement::Begin(v) => write!(f, "{}", v), - Statement::Cancel(v) => write!(f, "{}", v), - Statement::Commit(v) => write!(f, "{}", v), - Statement::Output(v) => write!(f, "{}", v), - Statement::Ifelse(v) => write!(f, "{}", v), - Statement::Select(v) => write!(f, "{}", v), - Statement::Create(v) => write!(f, "{}", v), - Statement::Update(v) => write!(f, "{}", v), - Statement::Relate(v) => write!(f, "{}", v), - Statement::Delete(v) => write!(f, "{}", v), - Statement::Insert(v) => write!(f, "{}", v), - Statement::Define(v) => write!(f, "{}", v), - Statement::Remove(v) => write!(f, "{}", v), - Statement::Option(v) => write!(f, "{}", v), + Self::Use(v) => Display::fmt(v, f), + Self::Set(v) => Display::fmt(v, f), + Self::Info(v) => Display::fmt(v, f), + Self::Live(v) => Display::fmt(v, f), + Self::Kill(v) => Display::fmt(v, f), + Self::Begin(v) => Display::fmt(v, f), + Self::Cancel(v) => Display::fmt(v, f), + Self::Commit(v) => Display::fmt(v, f), + Self::Output(v) => Display::fmt(v, f), + Self::Ifelse(v) => Display::fmt(v, f), + Self::Select(v) => Display::fmt(v, f), + Self::Create(v) => Display::fmt(v, f), + Self::Update(v) => Display::fmt(v, f), + Self::Relate(v) => Display::fmt(v, f), + Self::Delete(v) => Display::fmt(v, f), + Self::Insert(v) => Display::fmt(v, f), + Self::Define(v) => Display::fmt(v, f), + Self::Remove(v) => Display::fmt(v, f), + Self::Option(v) => Display::fmt(v, f), } } } diff --git a/lib/src/sql/statements/begin.rs b/lib/src/sql/statements/begin.rs index d85eabe0..7521a175 100644 --- a/lib/src/sql/statements/begin.rs +++ b/lib/src/sql/statements/begin.rs @@ -13,7 +13,7 @@ pub struct BeginStatement; impl fmt::Display for BeginStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "BEGIN TRANSACTION") + f.write_str("BEGIN TRANSACTION") } } diff --git a/lib/src/sql/statements/cancel.rs b/lib/src/sql/statements/cancel.rs index 742f8111..bd284902 100644 --- a/lib/src/sql/statements/cancel.rs +++ b/lib/src/sql/statements/cancel.rs @@ -13,7 +13,7 @@ pub struct CancelStatement; impl fmt::Display for CancelStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "CANCEL TRANSACTION") + f.write_str("CANCEL TRANSACTION") } } diff --git a/lib/src/sql/statements/commit.rs b/lib/src/sql/statements/commit.rs index 37d173ef..5bf15b69 100644 --- a/lib/src/sql/statements/commit.rs +++ b/lib/src/sql/statements/commit.rs @@ -13,7 +13,7 @@ pub struct CommitStatement; impl fmt::Display for CommitStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "COMMIT TRANSACTION") + f.write_str("COMMIT TRANSACTION") } } diff --git a/lib/src/sql/statements/create.rs b/lib/src/sql/statements/create.rs index a456e0a1..aa56e030 100644 --- a/lib/src/sql/statements/create.rs +++ b/lib/src/sql/statements/create.rs @@ -130,7 +130,7 @@ impl fmt::Display for CreateStatement { write!(f, " {}", v)? } if self.parallel { - write!(f, " PARALLEL")? + f.write_str(" PARALLEL")? } Ok(()) } diff --git a/lib/src/sql/statements/define.rs b/lib/src/sql/statements/define.rs index 88c5434f..28e8c4ef 100644 --- a/lib/src/sql/statements/define.rs +++ b/lib/src/sql/statements/define.rs @@ -31,6 +31,7 @@ use rand::rngs::OsRng; use rand::Rng; use serde::{Deserialize, Serialize}; use std::fmt; +use std::fmt::Display; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store)] pub enum DefineStatement { @@ -54,15 +55,15 @@ impl DefineStatement { doc: Option<&Value>, ) -> Result { match self { - DefineStatement::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Database(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Login(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Token(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Scope(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Table(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Event(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Field(ref v) => v.compute(ctx, opt, txn, doc).await, - DefineStatement::Index(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Database(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Login(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Token(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Scope(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Table(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Event(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Field(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Index(ref v) => v.compute(ctx, opt, txn, doc).await, } } } @@ -70,15 +71,15 @@ impl DefineStatement { impl fmt::Display for DefineStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - DefineStatement::Namespace(v) => write!(f, "{}", v), - DefineStatement::Database(v) => write!(f, "{}", v), - DefineStatement::Login(v) => write!(f, "{}", v), - DefineStatement::Token(v) => write!(f, "{}", v), - DefineStatement::Scope(v) => write!(f, "{}", v), - DefineStatement::Table(v) => write!(f, "{}", v), - DefineStatement::Event(v) => write!(f, "{}", v), - DefineStatement::Field(v) => write!(f, "{}", v), - DefineStatement::Index(v) => write!(f, "{}", v), + Self::Namespace(v) => Display::fmt(v, f), + Self::Database(v) => Display::fmt(v, f), + Self::Login(v) => Display::fmt(v, f), + Self::Token(v) => Display::fmt(v, f), + Self::Scope(v) => Display::fmt(v, f), + Self::Table(v) => Display::fmt(v, f), + Self::Event(v) => Display::fmt(v, f), + Self::Field(v) => Display::fmt(v, f), + Self::Index(v) => Display::fmt(v, f), } } } diff --git a/lib/src/sql/statements/delete.rs b/lib/src/sql/statements/delete.rs index 6f9e973e..f9e483a5 100644 --- a/lib/src/sql/statements/delete.rs +++ b/lib/src/sql/statements/delete.rs @@ -124,7 +124,7 @@ impl fmt::Display for DeleteStatement { write!(f, " {}", v)? } if self.parallel { - write!(f, " PARALLEL")? + f.write_str(" PARALLEL")? } Ok(()) } diff --git a/lib/src/sql/statements/info.rs b/lib/src/sql/statements/info.rs index 0cc17d23..1284657d 100644 --- a/lib/src/sql/statements/info.rs +++ b/lib/src/sql/statements/info.rs @@ -188,11 +188,11 @@ impl InfoStatement { impl fmt::Display for InfoStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - InfoStatement::Kv => write!(f, "INFO FOR KV"), - InfoStatement::Ns => write!(f, "INFO FOR NAMESPACE"), - InfoStatement::Db => write!(f, "INFO FOR DATABASE"), - InfoStatement::Sc(ref s) => write!(f, "INFO FOR SCOPE {}", s), - InfoStatement::Tb(ref t) => write!(f, "INFO FOR TABLE {}", t), + Self::Kv => f.write_str("INFO FOR KV"), + Self::Ns => f.write_str("INFO FOR NAMESPACE"), + Self::Db => f.write_str("INFO FOR DATABASE"), + Self::Sc(ref s) => write!(f, "INFO FOR SCOPE {}", s), + Self::Tb(ref t) => write!(f, "INFO FOR TABLE {}", t), } } } diff --git a/lib/src/sql/statements/insert.rs b/lib/src/sql/statements/insert.rs index f6eb6e05..3760c5d7 100644 --- a/lib/src/sql/statements/insert.rs +++ b/lib/src/sql/statements/insert.rs @@ -106,9 +106,9 @@ impl InsertStatement { impl fmt::Display for InsertStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "INSERT")?; + f.write_str("INSERT")?; if self.ignore { - write!(f, " IGNORE")? + f.write_str(" IGNORE")? } write!(f, " INTO {} {}", self.into, self.data)?; if let Some(ref v) = self.output { @@ -118,7 +118,7 @@ impl fmt::Display for InsertStatement { write!(f, " {}", v)? } if self.parallel { - write!(f, " PARALLEL")? + f.write_str(" PARALLEL")? } Ok(()) } diff --git a/lib/src/sql/statements/relate.rs b/lib/src/sql/statements/relate.rs index 201219a6..6a0f582d 100644 --- a/lib/src/sql/statements/relate.rs +++ b/lib/src/sql/statements/relate.rs @@ -172,7 +172,7 @@ impl fmt::Display for RelateStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "RELATE {} -> {} -> {}", self.from, self.kind, self.with)?; if self.uniq { - write!(f, " UNIQUE")? + f.write_str(" UNIQUE")? } if let Some(ref v) = self.data { write!(f, " {}", v)? @@ -184,7 +184,7 @@ impl fmt::Display for RelateStatement { write!(f, " {}", v)? } if self.parallel { - write!(f, " PARALLEL")? + f.write_str(" PARALLEL")? } Ok(()) } diff --git a/lib/src/sql/statements/remove.rs b/lib/src/sql/statements/remove.rs index e6b8d0a2..93f26469 100644 --- a/lib/src/sql/statements/remove.rs +++ b/lib/src/sql/statements/remove.rs @@ -16,7 +16,7 @@ use nom::bytes::complete::tag_no_case; use nom::combinator::{map, opt}; use nom::sequence::tuple; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store)] pub enum RemoveStatement { @@ -40,31 +40,31 @@ impl RemoveStatement { doc: Option<&Value>, ) -> Result { match self { - RemoveStatement::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Database(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Login(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Token(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Scope(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Table(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Event(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Field(ref v) => v.compute(ctx, opt, txn, doc).await, - RemoveStatement::Index(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Database(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Login(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Token(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Scope(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Table(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Event(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Field(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Index(ref v) => v.compute(ctx, opt, txn, doc).await, } } } -impl fmt::Display for RemoveStatement { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for RemoveStatement { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - RemoveStatement::Namespace(v) => write!(f, "{}", v), - RemoveStatement::Database(v) => write!(f, "{}", v), - RemoveStatement::Login(v) => write!(f, "{}", v), - RemoveStatement::Token(v) => write!(f, "{}", v), - RemoveStatement::Scope(v) => write!(f, "{}", v), - RemoveStatement::Table(v) => write!(f, "{}", v), - RemoveStatement::Event(v) => write!(f, "{}", v), - RemoveStatement::Field(v) => write!(f, "{}", v), - RemoveStatement::Index(v) => write!(f, "{}", v), + Self::Namespace(v) => Display::fmt(v, f), + Self::Database(v) => Display::fmt(v, f), + Self::Login(v) => Display::fmt(v, f), + Self::Token(v) => Display::fmt(v, f), + Self::Scope(v) => Display::fmt(v, f), + Self::Table(v) => Display::fmt(v, f), + Self::Event(v) => Display::fmt(v, f), + Self::Field(v) => Display::fmt(v, f), + Self::Index(v) => Display::fmt(v, f), } } } diff --git a/lib/src/sql/statements/select.rs b/lib/src/sql/statements/select.rs index 4e00f79e..02be4b27 100644 --- a/lib/src/sql/statements/select.rs +++ b/lib/src/sql/statements/select.rs @@ -157,7 +157,7 @@ impl fmt::Display for SelectStatement { write!(f, " {}", v)? } if self.parallel { - write!(f, " PARALLEL")? + f.write_str(" PARALLEL")? } Ok(()) } diff --git a/lib/src/sql/statements/update.rs b/lib/src/sql/statements/update.rs index d056a3e9..8430eb9a 100644 --- a/lib/src/sql/statements/update.rs +++ b/lib/src/sql/statements/update.rs @@ -128,7 +128,7 @@ impl fmt::Display for UpdateStatement { write!(f, " {}", v)? } if self.parallel { - write!(f, " PARALLEL")? + f.write_str(" PARALLEL")? } Ok(()) } diff --git a/lib/src/sql/statements/yuse.rs b/lib/src/sql/statements/yuse.rs index 1a4b9f9e..8b9b6ad6 100644 --- a/lib/src/sql/statements/yuse.rs +++ b/lib/src/sql/statements/yuse.rs @@ -15,7 +15,7 @@ pub struct UseStatement { impl fmt::Display for UseStatement { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "USE")?; + f.write_str("USE")?; if let Some(ref ns) = self.ns { write!(f, " NS {}", ns)?; } diff --git a/lib/src/sql/strand.rs b/lib/src/sql/strand.rs index 58083afa..09e59acc 100644 --- a/lib/src/sql/strand.rs +++ b/lib/src/sql/strand.rs @@ -8,7 +8,7 @@ use nom::bytes::complete::take_while_m_n; use nom::character::complete::char; use nom::combinator::value; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops; use std::ops::Deref; use std::str; @@ -30,7 +30,7 @@ impl From for Strand { impl From<&str> for Strand { fn from(s: &str) -> Self { - Strand(String::from(s)) + Self::from(String::from(s)) } } @@ -53,9 +53,9 @@ impl Strand { } } -impl fmt::Display for Strand { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", escape_strand(&self.0)) +impl Display for Strand { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&escape_strand(&self.0), f) } } diff --git a/lib/src/sql/subquery.rs b/lib/src/sql/subquery.rs index 61fb96bd..ed615e38 100644 --- a/lib/src/sql/subquery.rs +++ b/lib/src/sql/subquery.rs @@ -18,7 +18,7 @@ use nom::character::complete::char; use nom::combinator::map; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; -use std::fmt; +use std::fmt::{self, Display, Formatter}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum Subquery { @@ -42,14 +42,14 @@ impl PartialOrd for Subquery { impl Subquery { pub(crate) fn writeable(&self) -> bool { match self { - Subquery::Value(v) => v.writeable(), - Subquery::Ifelse(v) => v.writeable(), - Subquery::Select(v) => v.writeable(), - Subquery::Create(v) => v.writeable(), - Subquery::Update(v) => v.writeable(), - Subquery::Delete(v) => v.writeable(), - Subquery::Relate(v) => v.writeable(), - Subquery::Insert(v) => v.writeable(), + Self::Value(v) => v.writeable(), + Self::Ifelse(v) => v.writeable(), + Self::Select(v) => v.writeable(), + Self::Create(v) => v.writeable(), + Self::Update(v) => v.writeable(), + Self::Delete(v) => v.writeable(), + Self::Relate(v) => v.writeable(), + Self::Insert(v) => v.writeable(), } } @@ -61,9 +61,9 @@ impl Subquery { doc: Option<&Value>, ) -> Result { match self { - Subquery::Value(ref v) => v.compute(ctx, opt, txn, doc).await, - Subquery::Ifelse(ref v) => v.compute(ctx, opt, txn, doc).await, - Subquery::Select(ref v) => { + Self::Value(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Ifelse(ref v) => v.compute(ctx, opt, txn, doc).await, + Self::Select(ref v) => { // Duplicate options let opt = opt.dive()?; // Duplicate context @@ -86,7 +86,7 @@ impl Subquery { }, } } - Subquery::Create(ref v) => { + Self::Create(ref v) => { // Duplicate options let opt = opt.dive()?; // Duplicate context @@ -104,7 +104,7 @@ impl Subquery { v => Ok(v), } } - Subquery::Update(ref v) => { + Self::Update(ref v) => { // Duplicate options let opt = opt.dive()?; // Duplicate context @@ -122,7 +122,7 @@ impl Subquery { v => Ok(v), } } - Subquery::Delete(ref v) => { + Self::Delete(ref v) => { // Duplicate options let opt = opt.dive()?; // Duplicate context @@ -140,7 +140,7 @@ impl Subquery { v => Ok(v), } } - Subquery::Relate(ref v) => { + Self::Relate(ref v) => { // Duplicate options let opt = opt.dive()?; // Duplicate context @@ -158,7 +158,7 @@ impl Subquery { v => Ok(v), } } - Subquery::Insert(ref v) => { + Self::Insert(ref v) => { // Duplicate options let opt = opt.dive()?; // Duplicate context @@ -180,17 +180,17 @@ impl Subquery { } } -impl fmt::Display for Subquery { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl Display for Subquery { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Subquery::Value(v) => write!(f, "({})", v), - Subquery::Select(v) => write!(f, "({})", v), - Subquery::Create(v) => write!(f, "({})", v), - Subquery::Update(v) => write!(f, "({})", v), - Subquery::Delete(v) => write!(f, "({})", v), - Subquery::Relate(v) => write!(f, "({})", v), - Subquery::Insert(v) => write!(f, "({})", v), - Subquery::Ifelse(v) => write!(f, "{}", v), + Self::Value(v) => write!(f, "({})", v), + Self::Select(v) => write!(f, "({})", v), + Self::Create(v) => write!(f, "({})", v), + Self::Update(v) => write!(f, "({})", v), + Self::Delete(v) => write!(f, "({})", v), + Self::Relate(v) => write!(f, "({})", v), + Self::Insert(v) => write!(f, "({})", v), + Self::Ifelse(v) => Display::fmt(v, f), } } } diff --git a/lib/src/sql/table.rs b/lib/src/sql/table.rs index ca0bd7cd..f95bf7b1 100644 --- a/lib/src/sql/table.rs +++ b/lib/src/sql/table.rs @@ -1,12 +1,13 @@ use crate::sql::common::commas; use crate::sql::error::IResult; use crate::sql::escape::escape_ident; +use crate::sql::fmt::Fmt; use crate::sql::id::Id; use crate::sql::ident::{ident_raw, Ident}; use crate::sql::thing::Thing; use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; -use std::fmt; +use std::fmt::{self, Display, Formatter}; use std::ops::Deref; use std::str; @@ -26,9 +27,9 @@ impl Deref for Tables { } } -impl fmt::Display for Tables { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0.iter().map(|ref v| format!("{}", v)).collect::>().join(", ")) +impl Display for Tables { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&Fmt::comma_separated(&self.0), f) } } @@ -42,19 +43,19 @@ pub struct Table(pub String); impl From for Table { fn from(v: String) -> Self { - Table(v) + Self(v) } } impl From<&str> for Table { fn from(v: &str) -> Self { - Table(String::from(v)) + Self::from(String::from(v)) } } impl From for Table { fn from(v: Ident) -> Self { - Table(v.0) + Self(v.0) } } @@ -74,9 +75,9 @@ impl Table { } } -impl fmt::Display for Table { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", escape_ident(&self.0)) +impl Display for Table { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&escape_ident(&self.0), f) } } diff --git a/lib/src/sql/test.rs b/lib/src/sql/test.rs index e5664618..646e77dd 100644 --- a/lib/src/sql/test.rs +++ b/lib/src/sql/test.rs @@ -10,44 +10,44 @@ pub trait Parse { fn parse(val: &str) -> T; } -impl Parse for Value { - fn parse(val: &str) -> Value { +impl Parse for Value { + fn parse(val: &str) -> Self { value(val).unwrap().1 } } -impl Parse for Array { - fn parse(val: &str) -> Array { +impl Parse for Array { + fn parse(val: &str) -> Self { array(val).unwrap().1 } } -impl Parse for Param { - fn parse(val: &str) -> Param { +impl Parse for Param { + fn parse(val: &str) -> Self { param(val).unwrap().1 } } -impl Parse for Idiom { - fn parse(val: &str) -> Idiom { +impl Parse for Idiom { + fn parse(val: &str) -> Self { idiom(val).unwrap().1 } } -impl Parse