From c6fa14c0c842dac7dfc1126ad7a5cb5794461d32 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Sat, 28 Jan 2017 14:18:17 -0800 Subject: [PATCH] Rudimentary printing of EDN values. (#209) r=jsantell * Add a little From helper for edn::parse::ParseError. Not used yet. * Ignore more things. * Partly implement Display for edn::Value. --- .gitignore | 3 ++- edn/src/symbols.rs | 34 +++++++++++++++-------------- edn/src/types.rs | 46 +++++++++++++++++++++++++++++++++++++++ query-parser/src/error.rs | 6 +++++ 4 files changed, 72 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 7e07ff1d..07102c19 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.jar *jar *~ +*.rs.bk .s* .*.sw* *.rs.bak @@ -49,7 +50,7 @@ pom.xml.asc /release-node/datomish/ /release-node/goog/ /release-node/honeysql/ - /edn/target/ /fixtures/*.db-shm /fixtures/*.db-wal +/query-parser/out/ diff --git a/edn/src/symbols.rs b/edn/src/symbols.rs index e4395f3b..23e5e8f9 100644 --- a/edn/src/symbols.rs +++ b/edn/src/symbols.rs @@ -8,6 +8,8 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use std::fmt::{Display, Formatter}; + /// A simplification of Clojure's Symbol. #[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)] pub struct PlainSymbol(pub String); @@ -73,7 +75,7 @@ impl PlainSymbol { let n = name.into(); assert!(!n.is_empty(), "Symbols cannot be unnamed."); - return PlainSymbol(n); + PlainSymbol(n) } } @@ -82,7 +84,7 @@ impl NamespacedSymbol { assert!(!name.is_empty(), "Symbols cannot be unnamed."); assert!(!namespace.is_empty(), "Symbols cannot have an empty non-null namespace."); - return NamespacedSymbol { name: name.to_string(), namespace: namespace.to_string() }; + NamespacedSymbol { name: name.to_string(), namespace: namespace.to_string() } } } @@ -91,7 +93,7 @@ impl Keyword { let n = name.into(); assert!(!n.is_empty(), "Keywords cannot be unnamed."); - return Keyword(n); + Keyword(n) } } @@ -101,7 +103,7 @@ impl NamespacedKeyword { assert!(!namespace.is_empty(), "Keywords cannot have an empty non-null namespace."); // TODO: debug asserts to ensure that neither field matches [ :/]. - return NamespacedKeyword { name: name.to_string(), namespace: namespace.to_string() }; + NamespacedKeyword { name: name.to_string(), namespace: namespace.to_string() } } } @@ -109,7 +111,7 @@ impl NamespacedKeyword { // Note that we don't currently do any escaping. // -impl ToString for PlainSymbol { +impl Display for PlainSymbol { /// Print the symbol in EDN format. /// /// # Examples @@ -118,12 +120,12 @@ impl ToString for PlainSymbol { /// # use edn::symbols::PlainSymbol; /// assert_eq!("baz", PlainSymbol::new("baz").to_string()); /// ``` - fn to_string(&self) -> String { - return format!("{}", self.0); + fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.0) } } -impl ToString for NamespacedSymbol { +impl Display for NamespacedSymbol { /// Print the symbol in EDN format. /// /// # Examples @@ -132,12 +134,12 @@ impl ToString for NamespacedSymbol { /// # use edn::symbols::NamespacedSymbol; /// assert_eq!("bar/baz", NamespacedSymbol::new("bar", "baz").to_string()); /// ``` - fn to_string(&self) -> String { - return format!("{}/{}", self.namespace, self.name); + fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result { + write!(f, "{}/{}", self.namespace, self.name) } } -impl ToString for Keyword { +impl Display for Keyword { /// Print the keyword in EDN format. /// /// # Examples @@ -146,12 +148,12 @@ impl ToString for Keyword { /// # use edn::symbols::Keyword; /// assert_eq!(":baz", Keyword::new("baz").to_string()); /// ``` - fn to_string(&self) -> String { - return format!(":{}", self.0); + fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result { + write!(f, ":{}", self.0) } } -impl ToString for NamespacedKeyword { +impl Display for NamespacedKeyword { /// Print the keyword in EDN format. /// /// # Examples @@ -160,7 +162,7 @@ impl ToString for NamespacedKeyword { /// # use edn::symbols::NamespacedKeyword; /// assert_eq!(":bar/baz", NamespacedKeyword::new("bar", "baz").to_string()); /// ``` - fn to_string(&self) -> String { - return format!(":{}/{}", self.namespace, self.name); + fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result { + write!(f, ":{}/{}", self.namespace, self.name) } } diff --git a/edn/src/types.rs b/edn/src/types.rs index 8d3e8427..24a82815 100644 --- a/edn/src/types.rs +++ b/edn/src/types.rs @@ -10,6 +10,7 @@ use std::collections::{BTreeSet, BTreeMap, LinkedList}; use std::cmp::{Ordering, Ord, PartialOrd}; +use std::fmt::{Display, Formatter}; use symbols; use num::BigInt; @@ -41,6 +42,51 @@ pub enum Value { use self::Value::*; +impl Display for Value { + fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result { + match *self { + Keyword(ref v) => v.fmt(f), + NamespacedKeyword(ref v) => v.fmt(f), + PlainSymbol(ref v) => v.fmt(f), + NamespacedSymbol(ref v) => v.fmt(f), + + Integer(v) => write!(f, "{}", v), + BigInteger(ref v) => write!(f, "{}N", v), + Float(OrderedFloat(v)) => write!(f, "{}", v), // TODO: make sure float syntax is correct. + // TODO: NaN. + Text(ref v) => write!(f, "{}", v), // TODO: EDN escaping. + Vector(ref v) => { + try!(write!(f, "[")); + for x in v { + try!(write!(f, " {}", x)); + } + write!(f, " ]") + } + _ => + write!(f, "{}", + match *self { + Nil => "null", + Boolean(b) => if b { "true" } else { "false" }, + _ => unimplemented!(), + }), + } + } +} + +#[test] +fn test_print_edn() { + assert_eq!("[ 1 2 [ 3.1 ] [ ] :five :six/seven eight nine/ten true ]", + Value::Vector(vec!(Value::Integer(1), + Value::Integer(2), + Value::Vector(vec!(Value::Float(OrderedFloat(3.1)))), + Value::Vector(vec!()), + Value::Keyword(symbols::Keyword::new("five")), + Value::NamespacedKeyword(symbols::NamespacedKeyword::new("six", "seven")), + Value::PlainSymbol(symbols::PlainSymbol::new("eight")), + Value::NamespacedSymbol(symbols::NamespacedSymbol::new("nine", "ten")), + Value::Boolean(true))).to_string()); +} + impl Value { pub fn is_keyword(&self) -> bool { match *self { diff --git a/query-parser/src/error.rs b/query-parser/src/error.rs index 6704e0d4..8e264e96 100644 --- a/query-parser/src/error.rs +++ b/query-parser/src/error.rs @@ -30,6 +30,12 @@ pub enum QueryParseError { FindParseError(FindParseError), } +impl From for QueryParseError { + fn from(err: edn::parse::ParseError) -> QueryParseError { + QueryParseError::EdnParseError(err) + } +} + pub type FindParseResult = Result; pub type QueryParseResult = Result;