From d0214fad7d650f3f534031f9c93d1c60696f9bac Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Wed, 8 Aug 2018 10:36:41 -0700 Subject: [PATCH] Pre: Move core/types.rs into core_traits --- core-traits/Cargo.toml | 11 + core-traits/lib.rs | 805 ++++++++++++++++++++ {core/src => core-traits}/values.rs | 0 core/Cargo.toml | 3 - core/src/cache.rs | 2 +- core/src/lib.rs | 23 +- core/src/sql_types.rs | 10 +- core/src/types.rs | 810 --------------------- core/src/value_type_set.rs | 2 +- db/src/bootstrap.rs | 8 +- db/src/cache.rs | 4 +- db/src/db.rs | 4 +- db/src/debug.rs | 4 +- db/src/errors.rs | 3 - db/src/internal_types.rs | 4 +- db/src/metadata.rs | 4 +- db/src/schema.rs | 4 +- db/src/timelines.rs | 2 +- db/src/tx.rs | 6 +- db/src/tx_checking.rs | 3 - db/src/tx_observer.rs | 2 +- db/src/types.rs | 4 +- db/src/upsert_resolution.rs | 2 +- db/src/watcher.rs | 2 +- db/tests/value_tests.rs | 7 +- query-algebrizer/src/clauses/convert.rs | 7 +- query-algebrizer/src/clauses/fulltext.rs | 12 +- query-algebrizer/src/clauses/ground.rs | 12 +- query-algebrizer/src/clauses/inputs.rs | 4 +- query-algebrizer/src/clauses/mod.rs | 4 +- query-algebrizer/src/clauses/not.rs | 7 +- query-algebrizer/src/clauses/or.rs | 7 +- query-algebrizer/src/clauses/pattern.rs | 4 +- query-algebrizer/src/clauses/predicate.rs | 11 +- query-algebrizer/src/clauses/resolve.rs | 7 +- query-algebrizer/src/clauses/tx_log_api.rs | 9 +- query-algebrizer/src/errors.rs | 5 +- query-algebrizer/src/lib.rs | 4 +- query-algebrizer/src/types.rs | 4 +- query-algebrizer/tests/fulltext.rs | 5 +- query-algebrizer/tests/ground.rs | 7 +- query-algebrizer/tests/predicate.rs | 7 +- query-algebrizer/tests/type_reqs.rs | 7 +- query-algebrizer/tests/utils/mod.rs | 2 +- query-projector/src/aggregates.rs | 5 +- query-projector/src/binding_tuple.rs | 2 +- query-projector/src/lib.rs | 7 +- query-projector/src/pull.rs | 6 +- query-projector/src/relresult.rs | 2 +- query-projector/tests/aggregates.rs | 2 +- query-pull/src/lib.rs | 6 +- query-sql/src/lib.rs | 4 +- query-translator/src/lib.rs | 1 + query-translator/src/translate.rs | 7 +- query-translator/tests/translate.rs | 4 +- sql/Cargo.toml | 3 + sql/src/lib.rs | 6 +- src/conn.rs | 13 +- src/entity_builder.rs | 5 +- src/errors.rs | 5 +- src/lib.rs | 10 +- src/query.rs | 4 +- src/query_builder.rs | 6 +- src/store.rs | 11 +- tests/pull.rs | 8 +- tests/query.rs | 2 +- tests/tolstoy.rs | 3 - tolstoy/src/tx_processor.rs | 3 - tools/cli/Cargo.toml | 4 +- tools/cli/src/mentat_cli/lib.rs | 2 +- tools/cli/src/mentat_cli/repl.rs | 2 +- 71 files changed, 1033 insertions(+), 954 deletions(-) rename {core/src => core-traits}/values.rs (100%) diff --git a/core-traits/Cargo.toml b/core-traits/Cargo.toml index a3ead9ce..ed6ddee7 100644 --- a/core-traits/Cargo.toml +++ b/core-traits/Cargo.toml @@ -7,5 +7,16 @@ workspace = ".." name = "core_traits" path = "lib.rs" +[dependencies] +chrono = { version = "0.4", features = ["serde"] } +enum-set = "0.0.7" +lazy_static = "0.2" +indexmap = "1" +ordered-float = { version = "0.5", features = ["serde"] } +uuid = { version = "0.5", features = ["v4", "serde"] } +serde = { version = "1.0", features = ["rc"] } +serde_derive = "1.0" + [dependencies.edn] path = "../edn" +features = ["serde_support"] diff --git a/core-traits/lib.rs b/core-traits/lib.rs index 1ec67a02..fd93c47e 100644 --- a/core-traits/lib.rs +++ b/core-traits/lib.rs @@ -8,7 +8,61 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +extern crate enum_set; +extern crate ordered_float; +extern crate chrono; +extern crate indexmap; +#[macro_use] extern crate serde_derive; +extern crate uuid; extern crate edn; +#[macro_use] +extern crate lazy_static; + +use std::fmt; + +use std::ffi::{ + CString, +}; + +use std::ops::{ + Deref, +}; + +use std::os::raw::{ + c_char, +}; + +use std::rc::{ + Rc, +}; + +use std::sync::{ + Arc, +}; + +use indexmap::{ + IndexMap, +}; + +use enum_set::EnumSet; + +use ordered_float::OrderedFloat; + +use chrono::{ + DateTime, + Timelike, +}; + +use uuid::Uuid; + +use edn::{ + Cloned, + ValueRc, + Utc, + Keyword, + FromMicros, + FromRc, +}; use edn::entities::{ AttributePlace, @@ -18,6 +72,8 @@ use edn::entities::{ TransactableValueMarker, }; +pub mod values; + /// Represents one entid in the entid space. /// /// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite @@ -53,3 +109,752 @@ impl Into> for KnownEntid { ValuePlace::Entid(EntidOrIdent::Entid(self.0)) } } + +/// The attribute of each Mentat assertion has a :db/valueType constraining the value to a +/// particular set. Mentat recognizes the following :db/valueType values. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] +#[repr(u32)] +pub enum ValueType { + Ref, + Boolean, + Instant, + Long, + Double, + String, + Keyword, + Uuid, +} + +impl ValueType { + pub fn all_enums() -> EnumSet { + // TODO: lazy_static. + let mut s = EnumSet::new(); + s.insert(ValueType::Ref); + s.insert(ValueType::Boolean); + s.insert(ValueType::Instant); + s.insert(ValueType::Long); + s.insert(ValueType::Double); + s.insert(ValueType::String); + s.insert(ValueType::Keyword); + s.insert(ValueType::Uuid); + s + } +} + + +impl ::enum_set::CLike for ValueType { + fn to_u32(&self) -> u32 { + *self as u32 + } + + unsafe fn from_u32(v: u32) -> ValueType { + ::std::mem::transmute(v) + } +} + +impl ValueType { + pub fn into_keyword(self) -> Keyword { + Keyword::namespaced("db.type", match self { + ValueType::Ref => "ref", + ValueType::Boolean => "boolean", + ValueType::Instant => "instant", + ValueType::Long => "long", + ValueType::Double => "double", + ValueType::String => "string", + ValueType::Keyword => "keyword", + ValueType::Uuid => "uuid", + }) + } + + pub fn from_keyword(keyword: &Keyword) -> Option { + if keyword.namespace() != Some("db.type") { + return None; + } + + return match keyword.name() { + "ref" => Some(ValueType::Ref), + "boolean" => Some(ValueType::Boolean), + "instant" => Some(ValueType::Instant), + "long" => Some(ValueType::Long), + "double" => Some(ValueType::Double), + "string" => Some(ValueType::String), + "keyword" => Some(ValueType::Keyword), + "uuid" => Some(ValueType::Uuid), + _ => None, + } + } + + pub fn into_typed_value(self) -> TypedValue { + TypedValue::typed_ns_keyword("db.type", match self { + ValueType::Ref => "ref", + ValueType::Boolean => "boolean", + ValueType::Instant => "instant", + ValueType::Long => "long", + ValueType::Double => "double", + ValueType::String => "string", + ValueType::Keyword => "keyword", + ValueType::Uuid => "uuid", + }) + } + + pub fn into_edn_value(self) -> edn::Value { + match self { + ValueType::Ref => values::DB_TYPE_REF.clone(), + ValueType::Boolean => values::DB_TYPE_BOOLEAN.clone(), + ValueType::Instant => values::DB_TYPE_INSTANT.clone(), + ValueType::Long => values::DB_TYPE_LONG.clone(), + ValueType::Double => values::DB_TYPE_DOUBLE.clone(), + ValueType::String => values::DB_TYPE_STRING.clone(), + ValueType::Keyword => values::DB_TYPE_KEYWORD.clone(), + ValueType::Uuid => values::DB_TYPE_UUID.clone(), + } + } + + pub fn is_numeric(&self) -> bool { + match self { + &ValueType::Long | &ValueType::Double => true, + _ => false + } + } +} + +impl fmt::Display for ValueType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", match *self { + ValueType::Ref => ":db.type/ref", + ValueType::Boolean => ":db.type/boolean", + ValueType::Instant => ":db.type/instant", + ValueType::Long => ":db.type/long", + ValueType::Double => ":db.type/double", + ValueType::String => ":db.type/string", + ValueType::Keyword => ":db.type/keyword", + ValueType::Uuid => ":db.type/uuid", + }) + } +} + +/// `TypedValue` is the value type for programmatic use in transaction builders. +impl TransactableValueMarker for TypedValue {} + +/// Represents a value that can be stored in a Mentat store. +// TODO: expand to include :db.type/uri. https://github.com/mozilla/mentat/issues/201 +// TODO: JSON data type? https://github.com/mozilla/mentat/issues/31 +// TODO: BigInt? Bytes? +#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq, Serialize, Deserialize)] +pub enum TypedValue { + Ref(Entid), + Boolean(bool), + Long(i64), + Double(OrderedFloat), + Instant(DateTime), // Use `into()` to ensure truncation. + // TODO: &str throughout? + String(ValueRc), + Keyword(ValueRc), + Uuid(Uuid), // It's only 128 bits, so this should be acceptable to clone. +} + +impl From for TypedValue { + fn from(k: KnownEntid) -> TypedValue { + TypedValue::Ref(k.0) + } +} + +impl TypedValue { + /// Returns true if the provided type is `Some` and matches this value's type, or if the + /// provided type is `None`. + #[inline] + pub fn is_congruent_with>>(&self, t: T) -> bool { + t.into().map_or(true, |x| self.matches_type(x)) + } + + #[inline] + pub fn matches_type(&self, t: ValueType) -> bool { + self.value_type() == t + } + + pub fn value_type(&self) -> ValueType { + match self { + &TypedValue::Ref(_) => ValueType::Ref, + &TypedValue::Boolean(_) => ValueType::Boolean, + &TypedValue::Long(_) => ValueType::Long, + &TypedValue::Instant(_) => ValueType::Instant, + &TypedValue::Double(_) => ValueType::Double, + &TypedValue::String(_) => ValueType::String, + &TypedValue::Keyword(_) => ValueType::Keyword, + &TypedValue::Uuid(_) => ValueType::Uuid, + } + } + + /// Construct a new `TypedValue::Keyword` instance by cloning the provided + /// values and wrapping them in a new `ValueRc`. This is expensive, so this might + /// be best limited to tests. + pub fn typed_ns_keyword, T: AsRef>(ns: S, name: T) -> TypedValue { + Keyword::namespaced(ns.as_ref(), name.as_ref()).into() + } + + /// Construct a new `TypedValue::String` instance by cloning the provided + /// value and wrapping it in a new `ValueRc`. This is expensive, so this might + /// be best limited to tests. + pub fn typed_string>(s: S) -> TypedValue { + s.as_ref().into() + } + + pub fn current_instant() -> TypedValue { + Utc::now().into() + } + + /// Construct a new `TypedValue::Instant` instance from the provided + /// microsecond timestamp. + pub fn instant(micros: i64) -> TypedValue { + DateTime::::from_micros(micros).into() + } + + pub fn into_known_entid(self) -> Option { + match self { + TypedValue::Ref(v) => Some(KnownEntid(v)), + _ => None, + } + } + + pub fn into_entid(self) -> Option { + match self { + TypedValue::Ref(v) => Some(v), + _ => None, + } + } + + pub fn into_kw(self) -> Option> { + match self { + TypedValue::Keyword(v) => Some(v), + _ => None, + } + } + + pub fn into_boolean(self) -> Option { + match self { + TypedValue::Boolean(v) => Some(v), + _ => None, + } + } + + pub fn into_long(self) -> Option { + match self { + TypedValue::Long(v) => Some(v), + _ => None, + } + } + + pub fn into_double(self) -> Option { + match self { + TypedValue::Double(v) => Some(v.into_inner()), + _ => None, + } + } + + pub fn into_instant(self) -> Option> { + match self { + TypedValue::Instant(v) => Some(v), + _ => None, + } + } + + pub fn into_timestamp(self) -> Option { + match self { + TypedValue::Instant(v) => Some(v.timestamp()), + _ => None, + } + } + + pub fn into_string(self) -> Option> { + match self { + TypedValue::String(v) => Some(v), + _ => None, + } + } + + pub fn into_c_string(self) -> Option<*mut c_char> { + match self { + TypedValue::String(v) => { + // Get an independent copy of the string. + let s: String = v.cloned(); + + // Make a CString out of the new bytes. + let c: CString = CString::new(s).expect("String conversion failed!"); + + // Return a C-owned pointer. + Some(c.into_raw()) + }, + _ => None, + } + } + + pub fn into_kw_c_string(self) -> Option<*mut c_char> { + match self { + TypedValue::Keyword(v) => { + // Get an independent copy of the string. + let s: String = v.to_string(); + + // Make a CString out of the new bytes. + let c: CString = CString::new(s).expect("String conversion failed!"); + + // Return a C-owned pointer. + Some(c.into_raw()) + }, + _ => None, + } + } + + pub fn into_uuid_c_string(self) -> Option<*mut c_char> { + match self { + TypedValue::Uuid(v) => { + // Get an independent copy of the string. + let s: String = v.hyphenated().to_string(); + + // Make a CString out of the new bytes. + let c: CString = CString::new(s).expect("String conversion failed!"); + + // Return a C-owned pointer. + Some(c.into_raw()) + }, + _ => None, + } + } + + pub fn into_uuid(self) -> Option { + match self { + TypedValue::Uuid(v) => Some(v), + _ => None, + } + } + + pub fn into_uuid_string(self) -> Option { + match self { + TypedValue::Uuid(v) => Some(v.hyphenated().to_string()), + _ => None, + } + } +} + +// We don't do From or From 'cos it's ambiguous. + +impl From for TypedValue { + fn from(value: bool) -> TypedValue { + TypedValue::Boolean(value) + } +} + +/// Truncate the provided `DateTime` to microsecond precision, and return the corresponding +/// `TypedValue::Instant`. +impl From> for TypedValue { + fn from(value: DateTime) -> TypedValue { + TypedValue::Instant(value.microsecond_precision()) + } +} + +impl From for TypedValue { + fn from(value: Uuid) -> TypedValue { + TypedValue::Uuid(value) + } +} + +impl<'a> From<&'a str> for TypedValue { + fn from(value: &'a str) -> TypedValue { + TypedValue::String(ValueRc::new(value.to_string())) + } +} + +impl From> for TypedValue { + fn from(value: Arc) -> TypedValue { + TypedValue::String(ValueRc::from_arc(value)) + } +} + +impl From> for TypedValue { + fn from(value: Rc) -> TypedValue { + TypedValue::String(ValueRc::from_rc(value)) + } +} + +impl From> for TypedValue { + fn from(value: Box) -> TypedValue { + TypedValue::String(ValueRc::new(*value)) + } +} + +impl From for TypedValue { + fn from(value: String) -> TypedValue { + TypedValue::String(ValueRc::new(value)) + } +} + +impl From> for TypedValue { + fn from(value: Arc) -> TypedValue { + TypedValue::Keyword(ValueRc::from_arc(value)) + } +} + +impl From> for TypedValue { + fn from(value: Rc) -> TypedValue { + TypedValue::Keyword(ValueRc::from_rc(value)) + } +} + +impl From for TypedValue { + fn from(value: Keyword) -> TypedValue { + TypedValue::Keyword(ValueRc::new(value)) + } +} + +impl From for TypedValue { + fn from(value: u32) -> TypedValue { + TypedValue::Long(value as i64) + } +} + +impl From for TypedValue { + fn from(value: i32) -> TypedValue { + TypedValue::Long(value as i64) + } +} + +impl From for TypedValue { + fn from(value: f64) -> TypedValue { + TypedValue::Double(OrderedFloat(value)) + } +} + +trait MicrosecondPrecision { + /// Truncate the provided `DateTime` to microsecond precision. + fn microsecond_precision(self) -> Self; +} + +impl MicrosecondPrecision for DateTime { + fn microsecond_precision(self) -> DateTime { + let nanoseconds = self.nanosecond(); + if nanoseconds % 1000 == 0 { + return self; + } + let microseconds = nanoseconds / 1000; + let truncated = microseconds * 1000; + self.with_nanosecond(truncated).expect("valid timestamp") + } +} + + +/// The values bound in a query specification can be: +/// +/// * Vecs of structured values, for multi-valued component attributes or nested expressions. +/// * Single structured values, for single-valued component attributes or nested expressions. +/// * Single typed values, for simple attributes. +/// +/// The `Binding` enum defines these three options. +/// +/// Datomic also supports structured inputs; at present Mentat does not, but this type +/// would also serve that purpose. +/// +/// Note that maps are not ordered, and so `Binding` is neither `Ord` nor `PartialOrd`. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Binding { + Scalar(TypedValue), + Vec(ValueRc>), + Map(ValueRc), +} + +impl From for Binding where T: Into { + fn from(value: T) -> Self { + Binding::Scalar(value.into()) + } +} + +impl From for Binding { + fn from(value: StructuredMap) -> Self { + Binding::Map(ValueRc::new(value)) + } +} + +impl From> for Binding { + fn from(value: Vec) -> Self { + Binding::Vec(ValueRc::new(value)) + } +} + +impl Binding { + pub fn into_scalar(self) -> Option { + match self { + Binding::Scalar(v) => Some(v), + _ => None, + } + } + + pub fn into_vec(self) -> Option>> { + match self { + Binding::Vec(v) => Some(v), + _ => None, + } + } + + pub fn into_map(self) -> Option> { + match self { + Binding::Map(v) => Some(v), + _ => None, + } + } + + pub fn as_scalar(&self) -> Option<&TypedValue> { + match self { + &Binding::Scalar(ref v) => Some(v), + _ => None, + } + } + + pub fn as_vec(&self) -> Option<&Vec> { + match self { + &Binding::Vec(ref v) => Some(v), + _ => None, + } + } + + pub fn as_map(&self) -> Option<&StructuredMap> { + match self { + &Binding::Map(ref v) => Some(v), + _ => None, + } + } +} + +/// A pull expression expands a binding into a structure. The returned structure +/// associates attributes named in the input or retrieved from the store with values. +/// This association is a `StructuredMap`. +/// +/// Note that 'attributes' in Datomic's case can mean: +/// - Reversed attribute keywords (:artist/_country). +/// - An alias using `:as` (:artist/name :as "Band name"). +/// +/// We entirely support the former, and partially support the latter -- you can alias +/// using a different keyword only. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct StructuredMap(pub IndexMap, Binding>); + +impl Deref for StructuredMap { + type Target = IndexMap, Binding>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl StructuredMap { + pub fn insert(&mut self, name: N, value: B) where N: Into>, B: Into { + self.0.insert(name.into(), value.into()); + } +} + +impl From, Binding>> for StructuredMap { + fn from(src: IndexMap, Binding>) -> Self { + StructuredMap(src) + } +} + +// Mostly for testing. +impl From> for StructuredMap where T: Into { + fn from(value: Vec<(Keyword, T)>) -> Self { + let mut sm = StructuredMap::default(); + for (k, v) in value.into_iter() { + sm.insert(k, v); + } + sm + } +} + +impl Binding { + /// Returns true if the provided type is `Some` and matches this value's type, or if the + /// provided type is `None`. + #[inline] + pub fn is_congruent_with>>(&self, t: T) -> bool { + t.into().map_or(true, |x| self.matches_type(x)) + } + + #[inline] + pub fn matches_type(&self, t: ValueType) -> bool { + self.value_type() == Some(t) + } + + pub fn value_type(&self) -> Option { + match self { + &Binding::Scalar(ref v) => Some(v.value_type()), + + &Binding::Map(_) => None, + &Binding::Vec(_) => None, + } + } +} + +/// Return the current time as a UTC `DateTime` instance with microsecond precision. +pub fn now() -> DateTime { + Utc::now().microsecond_precision() +} + +impl Binding { + pub fn into_known_entid(self) -> Option { + match self { + Binding::Scalar(TypedValue::Ref(v)) => Some(KnownEntid(v)), + _ => None, + } + } + + pub fn into_entid(self) -> Option { + match self { + Binding::Scalar(TypedValue::Ref(v)) => Some(v), + _ => None, + } + } + + pub fn into_kw(self) -> Option> { + match self { + Binding::Scalar(TypedValue::Keyword(v)) => Some(v), + _ => None, + } + } + + pub fn into_boolean(self) -> Option { + match self { + Binding::Scalar(TypedValue::Boolean(v)) => Some(v), + _ => None, + } + } + + pub fn into_long(self) -> Option { + match self { + Binding::Scalar(TypedValue::Long(v)) => Some(v), + _ => None, + } + } + + pub fn into_double(self) -> Option { + match self { + Binding::Scalar(TypedValue::Double(v)) => Some(v.into_inner()), + _ => None, + } + } + + pub fn into_instant(self) -> Option> { + match self { + Binding::Scalar(TypedValue::Instant(v)) => Some(v), + _ => None, + } + } + + pub fn into_timestamp(self) -> Option { + match self { + Binding::Scalar(TypedValue::Instant(v)) => Some(v.timestamp()), + _ => None, + } + } + + pub fn into_string(self) -> Option> { + match self { + Binding::Scalar(TypedValue::String(v)) => Some(v), + _ => None, + } + } + + pub fn into_uuid(self) -> Option { + match self { + Binding::Scalar(TypedValue::Uuid(v)) => Some(v), + _ => None, + } + } + + pub fn into_uuid_string(self) -> Option { + match self { + Binding::Scalar(TypedValue::Uuid(v)) => Some(v.hyphenated().to_string()), + _ => None, + } + } + + pub fn into_c_string(self) -> Option<*mut c_char> { + match self { + Binding::Scalar(v) => v.into_c_string(), + _ => None, + } + } + + pub fn into_kw_c_string(self) -> Option<*mut c_char> { + match self { + Binding::Scalar(v) => v.into_kw_c_string(), + _ => None, + } + } + + pub fn into_uuid_c_string(self) -> Option<*mut c_char> { + match self { + Binding::Scalar(v) => v.into_uuid_c_string(), + _ => None, + } + } + + pub fn as_entid(&self) -> Option<&Entid> { + match self { + &Binding::Scalar(TypedValue::Ref(ref v)) => Some(v), + _ => None, + } + } + + pub fn as_kw(&self) -> Option<&ValueRc> { + match self { + &Binding::Scalar(TypedValue::Keyword(ref v)) => Some(v), + _ => None, + } + } + + pub fn as_boolean(&self) -> Option<&bool> { + match self { + &Binding::Scalar(TypedValue::Boolean(ref v)) => Some(v), + _ => None, + } + } + + pub fn as_long(&self) -> Option<&i64> { + match self { + &Binding::Scalar(TypedValue::Long(ref v)) => Some(v), + _ => None, + } + } + + pub fn as_double(&self) -> Option<&f64> { + match self { + &Binding::Scalar(TypedValue::Double(ref v)) => Some(&v.0), + _ => None, + } + } + + pub fn as_instant(&self) -> Option<&DateTime> { + match self { + &Binding::Scalar(TypedValue::Instant(ref v)) => Some(v), + _ => None, + } + } + + pub fn as_string(&self) -> Option<&ValueRc> { + match self { + &Binding::Scalar(TypedValue::String(ref v)) => Some(v), + _ => None, + } + } + + pub fn as_uuid(&self) -> Option<&Uuid> { + match self { + &Binding::Scalar(TypedValue::Uuid(ref v)) => Some(v), + _ => None, + } + } +} + +#[test] +fn test_typed_value() { + assert!(TypedValue::Boolean(false).is_congruent_with(None)); + assert!(TypedValue::Boolean(false).is_congruent_with(ValueType::Boolean)); + assert!(!TypedValue::typed_string("foo").is_congruent_with(ValueType::Boolean)); + assert!(TypedValue::typed_string("foo").is_congruent_with(ValueType::String)); + assert!(TypedValue::typed_string("foo").is_congruent_with(None)); +} diff --git a/core/src/values.rs b/core-traits/values.rs similarity index 100% rename from core/src/values.rs rename to core-traits/values.rs diff --git a/core/Cargo.toml b/core/Cargo.toml index 6aa5cf5b..38a8eed8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -8,11 +8,8 @@ chrono = { version = "0.4", features = ["serde"] } enum-set = "0.0.7" failure = "0.1.1" indexmap = "1" -lazy_static = "0.2" ordered-float = { version = "0.5", features = ["serde"] } uuid = { version = "0.5", features = ["v4", "serde"] } -serde = { version = "1.0", features = ["rc"] } -serde_derive = "1.0" [dependencies.core_traits] path = "../core-traits" diff --git a/core/src/cache.rs b/core/src/cache.rs index 44e7aaf5..85a3dbee 100644 --- a/core/src/cache.rs +++ b/core/src/cache.rs @@ -16,11 +16,11 @@ use std::collections::{ use core_traits::{ Entid, + TypedValue, }; use ::{ Schema, - TypedValue, }; pub trait CachedAttributes { diff --git a/core/src/lib.rs b/core/src/lib.rs index 012b4d6f..fc60b24b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -14,24 +14,18 @@ extern crate failure; extern crate indexmap; extern crate ordered_float; extern crate uuid; -extern crate serde; extern crate core_traits; -#[macro_use] -extern crate lazy_static; - -#[macro_use] -extern crate serde_derive; - extern crate edn; use core_traits::{ Entid, KnownEntid, + values, + ValueType, }; -pub mod values; mod cache; use std::collections::{ @@ -76,12 +70,7 @@ pub use tx_report::{ }; pub use types::{ - Binding, - StructuredMap, - TypedValue, - ValueType, ValueTypeTag, - now, }; pub use value_type_set::{ @@ -106,7 +95,9 @@ pub enum AttributeBitFlags { } pub mod attribute { - use TypedValue; + use core_traits::{ + TypedValue, + }; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] pub enum Unique { @@ -423,6 +414,10 @@ mod test { use std::str::FromStr; + use core_traits::{ + TypedValue, + }; + fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) { schema.entid_map.insert(e, i.clone()); schema.ident_map.insert(i, e); diff --git a/core/src/sql_types.rs b/core/src/sql_types.rs index 8678065c..1791df10 100644 --- a/core/src/sql_types.rs +++ b/core/src/sql_types.rs @@ -12,8 +12,11 @@ use std::collections::{ BTreeSet, }; -use types::{ +use core_traits::{ ValueType, +}; + +use types::{ ValueTypeTag, }; @@ -70,7 +73,10 @@ impl SQLValueType for ValueType { /// example, `1` is how we encode `true`. /// /// ``` - /// use mentat_core::{ValueType, SQLValueType}; + /// extern crate core_traits; + /// extern crate mentat_core; + /// use core_traits::ValueType; + /// use mentat_core::SQLValueType; /// assert!(!ValueType::Instant.accommodates_integer(1493399581314)); /// assert!(!ValueType::Instant.accommodates_integer(1493399581314000)); /// assert!(ValueType::Boolean.accommodates_integer(1)); diff --git a/core/src/types.rs b/core/src/types.rs index 0d6b9749..c4e15b05 100644 --- a/core/src/types.rs +++ b/core/src/types.rs @@ -8,814 +8,4 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -use ::std::convert::{ - AsRef, -}; - -use ::std::ffi::{ - CString, -}; - -use ::std::ops::{ - Deref, -}; - -use ::std::os::raw::c_char; - -use ::std::rc::{ - Rc, -}; - -use ::std::sync::{ - Arc, -}; - -use std::fmt; -use ::enum_set::EnumSet; - -use ::ordered_float::OrderedFloat; - -use ::uuid::Uuid; - -use ::chrono::{ - DateTime, - Timelike, // For truncation. -}; - -use ::indexmap::{ - IndexMap, -}; - -use ::edn::{ - self, - Cloned, - FromMicros, - FromRc, - Keyword, - Utc, - ValueRc, -}; - -use ::edn::entities::{ - TransactableValueMarker, -}; - -use values; - -use core_traits::{ - Entid, - KnownEntid, -}; - -impl From for TypedValue { - fn from(k: KnownEntid) -> TypedValue { - TypedValue::Ref(k.0) - } -} - -/// The attribute of each Mentat assertion has a :db/valueType constraining the value to a -/// particular set. Mentat recognizes the following :db/valueType values. -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] -#[repr(u32)] -pub enum ValueType { - Ref, - Boolean, - Instant, - Long, - Double, - String, - Keyword, - Uuid, -} - pub type ValueTypeTag = i32; - -impl ValueType { - pub fn all_enums() -> EnumSet { - // TODO: lazy_static. - let mut s = EnumSet::new(); - s.insert(ValueType::Ref); - s.insert(ValueType::Boolean); - s.insert(ValueType::Instant); - s.insert(ValueType::Long); - s.insert(ValueType::Double); - s.insert(ValueType::String); - s.insert(ValueType::Keyword); - s.insert(ValueType::Uuid); - s - } -} - - -impl ::enum_set::CLike for ValueType { - fn to_u32(&self) -> u32 { - *self as u32 - } - - unsafe fn from_u32(v: u32) -> ValueType { - ::std::mem::transmute(v) - } -} - -impl ValueType { - pub fn into_keyword(self) -> Keyword { - Keyword::namespaced("db.type", match self { - ValueType::Ref => "ref", - ValueType::Boolean => "boolean", - ValueType::Instant => "instant", - ValueType::Long => "long", - ValueType::Double => "double", - ValueType::String => "string", - ValueType::Keyword => "keyword", - ValueType::Uuid => "uuid", - }) - } - - pub fn from_keyword(keyword: &Keyword) -> Option { - if keyword.namespace() != Some("db.type") { - return None; - } - - return match keyword.name() { - "ref" => Some(ValueType::Ref), - "boolean" => Some(ValueType::Boolean), - "instant" => Some(ValueType::Instant), - "long" => Some(ValueType::Long), - "double" => Some(ValueType::Double), - "string" => Some(ValueType::String), - "keyword" => Some(ValueType::Keyword), - "uuid" => Some(ValueType::Uuid), - _ => None, - } - } - - pub fn into_typed_value(self) -> TypedValue { - TypedValue::typed_ns_keyword("db.type", match self { - ValueType::Ref => "ref", - ValueType::Boolean => "boolean", - ValueType::Instant => "instant", - ValueType::Long => "long", - ValueType::Double => "double", - ValueType::String => "string", - ValueType::Keyword => "keyword", - ValueType::Uuid => "uuid", - }) - } - - pub fn into_edn_value(self) -> edn::Value { - match self { - ValueType::Ref => values::DB_TYPE_REF.clone(), - ValueType::Boolean => values::DB_TYPE_BOOLEAN.clone(), - ValueType::Instant => values::DB_TYPE_INSTANT.clone(), - ValueType::Long => values::DB_TYPE_LONG.clone(), - ValueType::Double => values::DB_TYPE_DOUBLE.clone(), - ValueType::String => values::DB_TYPE_STRING.clone(), - ValueType::Keyword => values::DB_TYPE_KEYWORD.clone(), - ValueType::Uuid => values::DB_TYPE_UUID.clone(), - } - } - - pub fn is_numeric(&self) -> bool { - match self { - &ValueType::Long | &ValueType::Double => true, - _ => false - } - } -} - -impl fmt::Display for ValueType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", match *self { - ValueType::Ref => ":db.type/ref", - ValueType::Boolean => ":db.type/boolean", - ValueType::Instant => ":db.type/instant", - ValueType::Long => ":db.type/long", - ValueType::Double => ":db.type/double", - ValueType::String => ":db.type/string", - ValueType::Keyword => ":db.type/keyword", - ValueType::Uuid => ":db.type/uuid", - }) - } -} - -/// Represents a value that can be stored in a Mentat store. -// TODO: expand to include :db.type/uri. https://github.com/mozilla/mentat/issues/201 -// TODO: JSON data type? https://github.com/mozilla/mentat/issues/31 -// TODO: BigInt? Bytes? -#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq, Serialize, Deserialize)] -pub enum TypedValue { - Ref(Entid), - Boolean(bool), - Long(i64), - Double(OrderedFloat), - Instant(DateTime), // Use `into()` to ensure truncation. - // TODO: &str throughout? - String(ValueRc), - Keyword(ValueRc), - Uuid(Uuid), // It's only 128 bits, so this should be acceptable to clone. -} - -/// `TypedValue` is the value type for programmatic use in transaction builders. -impl TransactableValueMarker for TypedValue {} - -/// The values bound in a query specification can be: -/// -/// * Vecs of structured values, for multi-valued component attributes or nested expressions. -/// * Single structured values, for single-valued component attributes or nested expressions. -/// * Single typed values, for simple attributes. -/// -/// The `Binding` enum defines these three options. -/// -/// Datomic also supports structured inputs; at present Mentat does not, but this type -/// would also serve that purpose. -/// -/// Note that maps are not ordered, and so `Binding` is neither `Ord` nor `PartialOrd`. -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum Binding { - Scalar(TypedValue), - Vec(ValueRc>), - Map(ValueRc), -} - -impl From for Binding where T: Into { - fn from(value: T) -> Self { - Binding::Scalar(value.into()) - } -} - -impl From for Binding { - fn from(value: StructuredMap) -> Self { - Binding::Map(ValueRc::new(value)) - } -} - -impl From> for Binding { - fn from(value: Vec) -> Self { - Binding::Vec(ValueRc::new(value)) - } -} - -impl Binding { - pub fn into_scalar(self) -> Option { - match self { - Binding::Scalar(v) => Some(v), - _ => None, - } - } - - pub fn into_vec(self) -> Option>> { - match self { - Binding::Vec(v) => Some(v), - _ => None, - } - } - - pub fn into_map(self) -> Option> { - match self { - Binding::Map(v) => Some(v), - _ => None, - } - } - - pub fn as_scalar(&self) -> Option<&TypedValue> { - match self { - &Binding::Scalar(ref v) => Some(v), - _ => None, - } - } - - pub fn as_vec(&self) -> Option<&Vec> { - match self { - &Binding::Vec(ref v) => Some(v), - _ => None, - } - } - - pub fn as_map(&self) -> Option<&StructuredMap> { - match self { - &Binding::Map(ref v) => Some(v), - _ => None, - } - } -} - -/// A pull expression expands a binding into a structure. The returned structure -/// associates attributes named in the input or retrieved from the store with values. -/// This association is a `StructuredMap`. -/// -/// Note that 'attributes' in Datomic's case can mean: -/// - Reversed attribute keywords (:artist/_country). -/// - An alias using `:as` (:artist/name :as "Band name"). -/// -/// We entirely support the former, and partially support the latter -- you can alias -/// using a different keyword only. -#[derive(Clone, Debug, Default, Eq, PartialEq)] -pub struct StructuredMap(pub IndexMap, Binding>); - -impl Deref for StructuredMap { - type Target = IndexMap, Binding>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl StructuredMap { - pub fn insert(&mut self, name: N, value: B) where N: Into>, B: Into { - self.0.insert(name.into(), value.into()); - } -} - -impl From, Binding>> for StructuredMap { - fn from(src: IndexMap, Binding>) -> Self { - StructuredMap(src) - } -} - -// Mostly for testing. -impl From> for StructuredMap where T: Into { - fn from(value: Vec<(Keyword, T)>) -> Self { - let mut sm = StructuredMap::default(); - for (k, v) in value.into_iter() { - sm.insert(k, v); - } - sm - } -} - -impl Binding { - /// Returns true if the provided type is `Some` and matches this value's type, or if the - /// provided type is `None`. - #[inline] - pub fn is_congruent_with>>(&self, t: T) -> bool { - t.into().map_or(true, |x| self.matches_type(x)) - } - - #[inline] - pub fn matches_type(&self, t: ValueType) -> bool { - self.value_type() == Some(t) - } - - pub fn value_type(&self) -> Option { - match self { - &Binding::Scalar(ref v) => Some(v.value_type()), - - &Binding::Map(_) => None, - &Binding::Vec(_) => None, - } - } -} - - -impl TypedValue { - /// Returns true if the provided type is `Some` and matches this value's type, or if the - /// provided type is `None`. - #[inline] - pub fn is_congruent_with>>(&self, t: T) -> bool { - t.into().map_or(true, |x| self.matches_type(x)) - } - - #[inline] - pub fn matches_type(&self, t: ValueType) -> bool { - self.value_type() == t - } - - pub fn value_type(&self) -> ValueType { - match self { - &TypedValue::Ref(_) => ValueType::Ref, - &TypedValue::Boolean(_) => ValueType::Boolean, - &TypedValue::Long(_) => ValueType::Long, - &TypedValue::Instant(_) => ValueType::Instant, - &TypedValue::Double(_) => ValueType::Double, - &TypedValue::String(_) => ValueType::String, - &TypedValue::Keyword(_) => ValueType::Keyword, - &TypedValue::Uuid(_) => ValueType::Uuid, - } - } - - /// Construct a new `TypedValue::Keyword` instance by cloning the provided - /// values and wrapping them in a new `ValueRc`. This is expensive, so this might - /// be best limited to tests. - pub fn typed_ns_keyword, T: AsRef>(ns: S, name: T) -> TypedValue { - Keyword::namespaced(ns.as_ref(), name.as_ref()).into() - } - - /// Construct a new `TypedValue::String` instance by cloning the provided - /// value and wrapping it in a new `ValueRc`. This is expensive, so this might - /// be best limited to tests. - pub fn typed_string>(s: S) -> TypedValue { - s.as_ref().into() - } - - pub fn current_instant() -> TypedValue { - Utc::now().into() - } - - /// Construct a new `TypedValue::Instant` instance from the provided - /// microsecond timestamp. - pub fn instant(micros: i64) -> TypedValue { - DateTime::::from_micros(micros).into() - } -} - -trait MicrosecondPrecision { - /// Truncate the provided `DateTime` to microsecond precision. - fn microsecond_precision(self) -> Self; -} - -impl MicrosecondPrecision for DateTime { - fn microsecond_precision(self) -> DateTime { - let nanoseconds = self.nanosecond(); - if nanoseconds % 1000 == 0 { - return self; - } - let microseconds = nanoseconds / 1000; - let truncated = microseconds * 1000; - self.with_nanosecond(truncated).expect("valid timestamp") - } -} - -/// Return the current time as a UTC `DateTime` instance with microsecond precision. -pub fn now() -> DateTime { - Utc::now().microsecond_precision() -} - -// We don't do From or From 'cos it's ambiguous. - -impl From for TypedValue { - fn from(value: bool) -> TypedValue { - TypedValue::Boolean(value) - } -} - -/// Truncate the provided `DateTime` to microsecond precision, and return the corresponding -/// `TypedValue::Instant`. -impl From> for TypedValue { - fn from(value: DateTime) -> TypedValue { - TypedValue::Instant(value.microsecond_precision()) - } -} - -impl From for TypedValue { - fn from(value: Uuid) -> TypedValue { - TypedValue::Uuid(value) - } -} - -impl<'a> From<&'a str> for TypedValue { - fn from(value: &'a str) -> TypedValue { - TypedValue::String(ValueRc::new(value.to_string())) - } -} - -impl From> for TypedValue { - fn from(value: Arc) -> TypedValue { - TypedValue::String(ValueRc::from_arc(value)) - } -} - -impl From> for TypedValue { - fn from(value: Rc) -> TypedValue { - TypedValue::String(ValueRc::from_rc(value)) - } -} - -impl From> for TypedValue { - fn from(value: Box) -> TypedValue { - TypedValue::String(ValueRc::new(*value)) - } -} - -impl From for TypedValue { - fn from(value: String) -> TypedValue { - TypedValue::String(ValueRc::new(value)) - } -} - -impl From> for TypedValue { - fn from(value: Arc) -> TypedValue { - TypedValue::Keyword(ValueRc::from_arc(value)) - } -} - -impl From> for TypedValue { - fn from(value: Rc) -> TypedValue { - TypedValue::Keyword(ValueRc::from_rc(value)) - } -} - -impl From for TypedValue { - fn from(value: Keyword) -> TypedValue { - TypedValue::Keyword(ValueRc::new(value)) - } -} - -impl From for TypedValue { - fn from(value: u32) -> TypedValue { - TypedValue::Long(value as i64) - } -} - -impl From for TypedValue { - fn from(value: i32) -> TypedValue { - TypedValue::Long(value as i64) - } -} - -impl From for TypedValue { - fn from(value: f64) -> TypedValue { - TypedValue::Double(OrderedFloat(value)) - } -} - -impl TypedValue { - pub fn into_known_entid(self) -> Option { - match self { - TypedValue::Ref(v) => Some(KnownEntid(v)), - _ => None, - } - } - - pub fn into_entid(self) -> Option { - match self { - TypedValue::Ref(v) => Some(v), - _ => None, - } - } - - pub fn into_kw(self) -> Option> { - match self { - TypedValue::Keyword(v) => Some(v), - _ => None, - } - } - - pub fn into_boolean(self) -> Option { - match self { - TypedValue::Boolean(v) => Some(v), - _ => None, - } - } - - pub fn into_long(self) -> Option { - match self { - TypedValue::Long(v) => Some(v), - _ => None, - } - } - - pub fn into_double(self) -> Option { - match self { - TypedValue::Double(v) => Some(v.into_inner()), - _ => None, - } - } - - pub fn into_instant(self) -> Option> { - match self { - TypedValue::Instant(v) => Some(v), - _ => None, - } - } - - pub fn into_timestamp(self) -> Option { - match self { - TypedValue::Instant(v) => Some(v.timestamp()), - _ => None, - } - } - - pub fn into_string(self) -> Option> { - match self { - TypedValue::String(v) => Some(v), - _ => None, - } - } - - pub fn into_c_string(self) -> Option<*mut c_char> { - match self { - TypedValue::String(v) => { - // Get an independent copy of the string. - let s: String = v.cloned(); - - // Make a CString out of the new bytes. - let c: CString = CString::new(s).expect("String conversion failed!"); - - // Return a C-owned pointer. - Some(c.into_raw()) - }, - _ => None, - } - } - - pub fn into_kw_c_string(self) -> Option<*mut c_char> { - match self { - TypedValue::Keyword(v) => { - // Get an independent copy of the string. - let s: String = v.to_string(); - - // Make a CString out of the new bytes. - let c: CString = CString::new(s).expect("String conversion failed!"); - - // Return a C-owned pointer. - Some(c.into_raw()) - }, - _ => None, - } - } - - pub fn into_uuid_c_string(self) -> Option<*mut c_char> { - match self { - TypedValue::Uuid(v) => { - // Get an independent copy of the string. - let s: String = v.hyphenated().to_string(); - - // Make a CString out of the new bytes. - let c: CString = CString::new(s).expect("String conversion failed!"); - - // Return a C-owned pointer. - Some(c.into_raw()) - }, - _ => None, - } - } - - pub fn into_uuid(self) -> Option { - match self { - TypedValue::Uuid(v) => Some(v), - _ => None, - } - } - - pub fn into_uuid_string(self) -> Option { - match self { - TypedValue::Uuid(v) => Some(v.hyphenated().to_string()), - _ => None, - } - } -} - -impl Binding { - pub fn into_known_entid(self) -> Option { - match self { - Binding::Scalar(TypedValue::Ref(v)) => Some(KnownEntid(v)), - _ => None, - } - } - - pub fn into_entid(self) -> Option { - match self { - Binding::Scalar(TypedValue::Ref(v)) => Some(v), - _ => None, - } - } - - pub fn into_kw(self) -> Option> { - match self { - Binding::Scalar(TypedValue::Keyword(v)) => Some(v), - _ => None, - } - } - - pub fn into_boolean(self) -> Option { - match self { - Binding::Scalar(TypedValue::Boolean(v)) => Some(v), - _ => None, - } - } - - pub fn into_long(self) -> Option { - match self { - Binding::Scalar(TypedValue::Long(v)) => Some(v), - _ => None, - } - } - - pub fn into_double(self) -> Option { - match self { - Binding::Scalar(TypedValue::Double(v)) => Some(v.into_inner()), - _ => None, - } - } - - pub fn into_instant(self) -> Option> { - match self { - Binding::Scalar(TypedValue::Instant(v)) => Some(v), - _ => None, - } - } - - pub fn into_timestamp(self) -> Option { - match self { - Binding::Scalar(TypedValue::Instant(v)) => Some(v.timestamp()), - _ => None, - } - } - - pub fn into_string(self) -> Option> { - match self { - Binding::Scalar(TypedValue::String(v)) => Some(v), - _ => None, - } - } - - pub fn into_uuid(self) -> Option { - match self { - Binding::Scalar(TypedValue::Uuid(v)) => Some(v), - _ => None, - } - } - - pub fn into_uuid_string(self) -> Option { - match self { - Binding::Scalar(TypedValue::Uuid(v)) => Some(v.hyphenated().to_string()), - _ => None, - } - } - - pub fn into_c_string(self) -> Option<*mut c_char> { - match self { - Binding::Scalar(v) => v.into_c_string(), - _ => None, - } - } - - pub fn into_kw_c_string(self) -> Option<*mut c_char> { - match self { - Binding::Scalar(v) => v.into_kw_c_string(), - _ => None, - } - } - - pub fn into_uuid_c_string(self) -> Option<*mut c_char> { - match self { - Binding::Scalar(v) => v.into_uuid_c_string(), - _ => None, - } - } - - pub fn as_entid(&self) -> Option<&Entid> { - match self { - &Binding::Scalar(TypedValue::Ref(ref v)) => Some(v), - _ => None, - } - } - - pub fn as_kw(&self) -> Option<&ValueRc> { - match self { - &Binding::Scalar(TypedValue::Keyword(ref v)) => Some(v), - _ => None, - } - } - - pub fn as_boolean(&self) -> Option<&bool> { - match self { - &Binding::Scalar(TypedValue::Boolean(ref v)) => Some(v), - _ => None, - } - } - - pub fn as_long(&self) -> Option<&i64> { - match self { - &Binding::Scalar(TypedValue::Long(ref v)) => Some(v), - _ => None, - } - } - - pub fn as_double(&self) -> Option<&f64> { - match self { - &Binding::Scalar(TypedValue::Double(ref v)) => Some(&v.0), - _ => None, - } - } - - pub fn as_instant(&self) -> Option<&DateTime> { - match self { - &Binding::Scalar(TypedValue::Instant(ref v)) => Some(v), - _ => None, - } - } - - pub fn as_string(&self) -> Option<&ValueRc> { - match self { - &Binding::Scalar(TypedValue::String(ref v)) => Some(v), - _ => None, - } - } - - pub fn as_uuid(&self) -> Option<&Uuid> { - match self { - &Binding::Scalar(TypedValue::Uuid(ref v)) => Some(v), - _ => None, - } - } -} - -#[test] -fn test_typed_value() { - assert!(TypedValue::Boolean(false).is_congruent_with(None)); - assert!(TypedValue::Boolean(false).is_congruent_with(ValueType::Boolean)); - assert!(!TypedValue::typed_string("foo").is_congruent_with(ValueType::Boolean)); - assert!(TypedValue::typed_string("foo").is_congruent_with(ValueType::String)); - assert!(TypedValue::typed_string("foo").is_congruent_with(None)); -} diff --git a/core/src/value_type_set.rs b/core/src/value_type_set.rs index 1629aa71..c194c57b 100644 --- a/core/src/value_type_set.rs +++ b/core/src/value_type_set.rs @@ -12,7 +12,7 @@ use ::enum_set::{ EnumSet, }; -use ::types::{ +use core_traits::{ ValueType, }; diff --git a/db/src/bootstrap.rs b/db/src/bootstrap.rs index 4584284d..5b4b847e 100644 --- a/db/src/bootstrap.rs +++ b/db/src/bootstrap.rs @@ -20,11 +20,15 @@ use edn::symbols; use entids; use db::TypedSQLValue; use edn::entities::Entity; + +use core_traits::{ + TypedValue, + values, +}; + use mentat_core::{ IdentMap, Schema, - TypedValue, - values, }; use schema::SchemaBuilding; use types::{Partition, PartitionMap}; diff --git a/db/src/cache.rs b/db/src/cache.rs index 1c1ce5f2..7f7e7dc8 100644 --- a/db/src/cache.rs +++ b/db/src/cache.rs @@ -79,15 +79,15 @@ use failure::{ use rusqlite; use core_traits::{ + Binding, Entid, + TypedValue, }; use mentat_core::{ - Binding, CachedAttributes, HasSchema, Schema, - TypedValue, UpdateableCache, ValueRc, }; diff --git a/db/src/db.rs b/db/src/db.rs index df4c00d7..20803b02 100644 --- a/db/src/db.rs +++ b/db/src/db.rs @@ -43,6 +43,8 @@ use entids; use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ @@ -53,9 +55,7 @@ use mentat_core::{ IdentMap, Schema, AttributeMap, - TypedValue, ToMicros, - ValueType, ValueRc, }; diff --git a/db/src/debug.rs b/db/src/debug.rs index da2fedef..8b755e90 100644 --- a/db/src/debug.rs +++ b/db/src/debug.rs @@ -69,14 +69,14 @@ use errors::Result; use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ HasSchema, SQLValueType, TxReport, - TypedValue, - ValueType, }; use edn::{ InternSet, diff --git a/db/src/errors.rs b/db/src/errors.rs index 5ed46924..2f6a8bb2 100644 --- a/db/src/errors.rs +++ b/db/src/errors.rs @@ -30,9 +30,6 @@ use edn::entities::{ use core_traits::{ Entid, KnownEntid, -}; - -use types::{ TypedValue, ValueType, }; diff --git a/db/src/internal_types.rs b/db/src/internal_types.rs index 98a958dd..d6ac2641 100644 --- a/db/src/internal_types.rs +++ b/db/src/internal_types.rs @@ -21,6 +21,8 @@ use std::collections::{ use core_traits::{ Entid, KnownEntid, + TypedValue, + ValueType, }; use mentat_core::util::Either; @@ -53,8 +55,6 @@ use types::{ AVPair, Schema, TransactableValue, - TypedValue, - ValueType, }; impl TransactableValue for ValueAndSpan { diff --git a/db/src/metadata.rs b/db/src/metadata.rs index 189a840d..cecdc27e 100644 --- a/db/src/metadata.rs +++ b/db/src/metadata.rs @@ -41,14 +41,14 @@ use errors::{ use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ attribute, Schema, AttributeMap, - TypedValue, - ValueType, }; use schema::{ diff --git a/db/src/schema.rs b/db/src/schema.rs index 29e9a7ce..5e1a829a 100644 --- a/db/src/schema.rs +++ b/db/src/schema.rs @@ -21,6 +21,8 @@ use edn::symbols; use core_traits::{ Entid, KnownEntid, + TypedValue, + ValueType, }; use mentat_core::{ @@ -31,8 +33,6 @@ use mentat_core::{ IdentMap, Schema, AttributeMap, - TypedValue, - ValueType, }; use metadata; use metadata::{ diff --git a/db/src/timelines.rs b/db/src/timelines.rs index 971e987e..ca00f633 100644 --- a/db/src/timelines.rs +++ b/db/src/timelines.rs @@ -20,11 +20,11 @@ use errors::{ use core_traits::{ Entid, KnownEntid, + TypedValue, }; use mentat_core::{ Schema, - TypedValue, }; use edn::{ diff --git a/db/src/tx.rs b/db/src/tx.rs index 09badf21..d104cbb2 100644 --- a/db/src/tx.rs +++ b/db/src/tx.rs @@ -92,6 +92,9 @@ use mentat_core::util::Either; use core_traits::{ Entid, KnownEntid, + TypedValue, + ValueType, + now, }; use mentat_core::{ @@ -100,7 +103,6 @@ use mentat_core::{ TxReport, Utc, attribute, - now, }; use edn::entities as entmod; @@ -122,8 +124,6 @@ use types::{ Attribute, PartitionMap, TransactableValue, - TypedValue, - ValueType, }; use upsert_resolution::{ FinalPopulations, diff --git a/db/src/tx_checking.rs b/db/src/tx_checking.rs index 0d84b96d..56a51a6a 100644 --- a/db/src/tx_checking.rs +++ b/db/src/tx_checking.rs @@ -15,9 +15,6 @@ use std::collections::{ use core_traits::{ Entid, -}; - -use mentat_core::{ TypedValue, ValueType, }; diff --git a/db/src/tx_observer.rs b/db/src/tx_observer.rs index 589752be..f65478d8 100644 --- a/db/src/tx_observer.rs +++ b/db/src/tx_observer.rs @@ -28,11 +28,11 @@ use indexmap::{ use core_traits::{ Entid, + TypedValue, }; use mentat_core::{ Schema, - TypedValue, }; use edn::entities::{ diff --git a/db/src/types.rs b/db/src/types.rs index 208e0116..b87d86c4 100644 --- a/db/src/types.rs +++ b/db/src/types.rs @@ -28,6 +28,8 @@ extern crate mentat_core; use core_traits::{ Entid, + TypedValue, + ValueType, }; pub use self::mentat_core::{ @@ -35,9 +37,7 @@ pub use self::mentat_core::{ AttributeBitFlags, DateTime, Schema, - TypedValue, Utc, - ValueType, }; use edn::entities::{ diff --git a/db/src/upsert_resolution.rs b/db/src/upsert_resolution.rs index 2d9a6816..55576c56 100644 --- a/db/src/upsert_resolution.rs +++ b/db/src/upsert_resolution.rs @@ -42,13 +42,13 @@ use mentat_core::util::Either::*; use core_traits::{ Entid, + TypedValue, }; use mentat_core::{ attribute, Attribute, Schema, - TypedValue, }; use edn::entities::OpType; use schema::SchemaBuilding; diff --git a/db/src/watcher.rs b/db/src/watcher.rs index 1deb4585..8a8c628a 100644 --- a/db/src/watcher.rs +++ b/db/src/watcher.rs @@ -19,11 +19,11 @@ use core_traits::{ Entid, + TypedValue, }; use mentat_core::{ Schema, - TypedValue, }; use edn::entities::{ diff --git a/db/tests/value_tests.rs b/db/tests/value_tests.rs index 4d76af6f..995b674b 100644 --- a/db/tests/value_tests.rs +++ b/db/tests/value_tests.rs @@ -9,7 +9,7 @@ // specific language governing permissions and limitations under the License. extern crate edn; -extern crate mentat_core; +extern crate core_traits; extern crate mentat_db; extern crate ordered_float; extern crate rusqlite; @@ -18,7 +18,10 @@ use ordered_float::OrderedFloat; use edn::symbols; -use mentat_core::{TypedValue, ValueType}; +use core_traits::{ + TypedValue, + ValueType, +}; use mentat_db::db::TypedSQLValue; // It's not possible to test to_sql_value_pair since rusqlite::ToSqlOutput doesn't implement diff --git a/query-algebrizer/src/clauses/convert.rs b/query-algebrizer/src/clauses/convert.rs index f4a1ad93..a718048a 100644 --- a/query-algebrizer/src/clauses/convert.rs +++ b/query-algebrizer/src/clauses/convert.rs @@ -8,12 +8,15 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use core_traits::{ + ValueType, + TypedValue, +}; + use mentat_core::{ HasSchema, Schema, SQLValueType, - TypedValue, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/src/clauses/fulltext.rs b/query-algebrizer/src/clauses/fulltext.rs index 6f5159f4..a2f7532f 100644 --- a/query-algebrizer/src/clauses/fulltext.rs +++ b/query-algebrizer/src/clauses/fulltext.rs @@ -8,10 +8,13 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use core_traits::{ + ValueType, + TypedValue, +}; + use mentat_core::{ HasSchema, - TypedValue, - ValueType, }; use mentat_core::util::Either; @@ -261,10 +264,13 @@ impl ConjoiningClauses { mod testing { use super::*; + use core_traits::{ + ValueType, + }; + use mentat_core::{ Attribute, Schema, - ValueType, }; use mentat_query::{ diff --git a/query-algebrizer/src/clauses/ground.rs b/query-algebrizer/src/clauses/ground.rs index 2e18ef7e..e9d14ab7 100644 --- a/query-algebrizer/src/clauses/ground.rs +++ b/query-algebrizer/src/clauses/ground.rs @@ -8,10 +8,13 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use core_traits::{ + ValueType, + TypedValue, +}; + use mentat_core::{ Schema, - TypedValue, - ValueType, ValueTypeSet, }; @@ -321,9 +324,12 @@ impl ConjoiningClauses { mod testing { use super::*; + use core_traits::{ + ValueType, + }; + use mentat_core::{ Attribute, - ValueType, }; use mentat_query::{ diff --git a/query-algebrizer/src/clauses/inputs.rs b/query-algebrizer/src/clauses/inputs.rs index 35c4371d..38b2eca4 100644 --- a/query-algebrizer/src/clauses/inputs.rs +++ b/query-algebrizer/src/clauses/inputs.rs @@ -10,9 +10,9 @@ use std::collections::BTreeMap; -use mentat_core::{ - TypedValue, +use core_traits::{ ValueType, + TypedValue, }; use mentat_query::{ diff --git a/query-algebrizer/src/clauses/mod.rs b/query-algebrizer/src/clauses/mod.rs index 31e259b7..0692ef1e 100644 --- a/query-algebrizer/src/clauses/mod.rs +++ b/query-algebrizer/src/clauses/mod.rs @@ -28,6 +28,8 @@ use std::fmt::{ use core_traits::{ Entid, KnownEntid, + ValueType, + TypedValue, }; use mentat_core::{ @@ -35,8 +37,6 @@ use mentat_core::{ Cloned, HasSchema, Schema, - TypedValue, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/src/clauses/not.rs b/query-algebrizer/src/clauses/not.rs index 7330342f..53cfa7bc 100644 --- a/query-algebrizer/src/clauses/not.rs +++ b/query-algebrizer/src/clauses/not.rs @@ -90,11 +90,14 @@ mod testing { use super::*; + use core_traits::{ + TypedValue, + ValueType, + }; + use mentat_core::{ Attribute, Schema, - TypedValue, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/src/clauses/or.rs b/query-algebrizer/src/clauses/or.rs index 53918e52..1399e591 100644 --- a/query-algebrizer/src/clauses/or.rs +++ b/query-algebrizer/src/clauses/or.rs @@ -753,11 +753,14 @@ fn union_types(into: &mut BTreeMap, mod testing { use super::*; + use core_traits::{ + ValueType, + TypedValue, + }; + use mentat_core::{ Attribute, Schema, - TypedValue, - ValueType, }; use mentat_query::{ diff --git a/query-algebrizer/src/clauses/pattern.rs b/query-algebrizer/src/clauses/pattern.rs index bd06fcb3..fd494fdb 100644 --- a/query-algebrizer/src/clauses/pattern.rs +++ b/query-algebrizer/src/clauses/pattern.rs @@ -10,13 +10,13 @@ use core_traits::{ Entid, + ValueType, + TypedValue, }; use mentat_core::{ Cloned, HasSchema, - TypedValue, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/src/clauses/predicate.rs b/query-algebrizer/src/clauses/predicate.rs index e58ecf7f..f958e18f 100644 --- a/query-algebrizer/src/clauses/predicate.rs +++ b/query-algebrizer/src/clauses/predicate.rs @@ -8,9 +8,12 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use core_traits::{ + ValueType, +}; + use mentat_core::{ Schema, - ValueType, ValueTypeSet, }; @@ -188,11 +191,13 @@ mod testing { use super::*; use mentat_core::attribute::Unique; - use mentat_core::{ - Attribute, + use core_traits::{ TypedValue, ValueType, }; + use mentat_core::{ + Attribute, + }; use mentat_query::{ FnArg, diff --git a/query-algebrizer/src/clauses/resolve.rs b/query-algebrizer/src/clauses/resolve.rs index 87a18cf3..648a9e1a 100644 --- a/query-algebrizer/src/clauses/resolve.rs +++ b/query-algebrizer/src/clauses/resolve.rs @@ -8,11 +8,14 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use core_traits::{ + ValueType, + TypedValue, +}; + use mentat_core::{ HasSchema, Schema, - TypedValue, - ValueType, }; use mentat_query::{ diff --git a/query-algebrizer/src/clauses/tx_log_api.rs b/query-algebrizer/src/clauses/tx_log_api.rs index 9c487be8..e4ea4985 100644 --- a/query-algebrizer/src/clauses/tx_log_api.rs +++ b/query-algebrizer/src/clauses/tx_log_api.rs @@ -8,7 +8,7 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -use mentat_core::{ +use core_traits::{ ValueType, }; @@ -248,12 +248,15 @@ impl ConjoiningClauses { mod testing { use super::*; - use mentat_core::{ - Schema, + use core_traits::{ TypedValue, ValueType, }; + use mentat_core::{ + Schema, + }; + use mentat_query::{ Binding, FnArg, diff --git a/query-algebrizer/src/errors.rs b/query-algebrizer/src/errors.rs index 20f0979a..085763e5 100644 --- a/query-algebrizer/src/errors.rs +++ b/query-algebrizer/src/errors.rs @@ -12,9 +12,12 @@ extern crate mentat_query; use std; // To refer to std::result::Result. +use core_traits::{ + ValueType, +}; + use mentat_core::{ EdnParseError, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/src/lib.rs b/query-algebrizer/src/lib.rs index 87aa7d97..9d63e537 100644 --- a/query-algebrizer/src/lib.rs +++ b/query-algebrizer/src/lib.rs @@ -28,13 +28,13 @@ mod clauses; use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ CachedAttributes, Schema, - TypedValue, - ValueType, parse_query, }; diff --git a/query-algebrizer/src/types.rs b/query-algebrizer/src/types.rs index 0cc018ef..16df8cbb 100644 --- a/query-algebrizer/src/types.rs +++ b/query-algebrizer/src/types.rs @@ -16,12 +16,12 @@ use std::fmt::{ use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ - TypedValue, ValueRc, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/tests/fulltext.rs b/query-algebrizer/tests/fulltext.rs index 3c735dec..6bb224a3 100644 --- a/query-algebrizer/tests/fulltext.rs +++ b/query-algebrizer/tests/fulltext.rs @@ -15,10 +15,13 @@ extern crate mentat_query_algebrizer; mod utils; +use core_traits::{ + ValueType, +}; + use mentat_core::{ Attribute, Schema, - ValueType, }; use mentat_query::{ diff --git a/query-algebrizer/tests/ground.rs b/query-algebrizer/tests/ground.rs index 447fa1fa..5cce5cd1 100644 --- a/query-algebrizer/tests/ground.rs +++ b/query-algebrizer/tests/ground.rs @@ -17,11 +17,14 @@ mod utils; use std::collections::BTreeMap; +use core_traits::{ + ValueType, + TypedValue, +}; + use mentat_core::{ Attribute, Schema, - ValueType, - TypedValue, }; use mentat_query::{ diff --git a/query-algebrizer/tests/predicate.rs b/query-algebrizer/tests/predicate.rs index 0e5e2922..c85a9b07 100644 --- a/query-algebrizer/tests/predicate.rs +++ b/query-algebrizer/tests/predicate.rs @@ -15,13 +15,16 @@ extern crate mentat_query_algebrizer; mod utils; +use core_traits::{ + ValueType, + TypedValue, +}; + use mentat_core::{ Attribute, DateTime, Schema, - TypedValue, Utc, - ValueType, ValueTypeSet, }; diff --git a/query-algebrizer/tests/type_reqs.rs b/query-algebrizer/tests/type_reqs.rs index 3bdca15a..e87b641f 100644 --- a/query-algebrizer/tests/type_reqs.rs +++ b/query-algebrizer/tests/type_reqs.rs @@ -8,8 +8,8 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -extern crate mentat_core; extern crate core_traits; +extern crate mentat_core; extern crate mentat_query; extern crate mentat_query_algebrizer; @@ -21,9 +21,12 @@ use utils::{ bails, }; +use core_traits::{ + ValueType, +}; + use mentat_core::{ Schema, - ValueType, }; use mentat_query_algebrizer::Known; diff --git a/query-algebrizer/tests/utils/mod.rs b/query-algebrizer/tests/utils/mod.rs index 488f9f58..1138e8c4 100644 --- a/query-algebrizer/tests/utils/mod.rs +++ b/query-algebrizer/tests/utils/mod.rs @@ -15,12 +15,12 @@ use core_traits::{ Entid, + ValueType, }; use mentat_core::{ Attribute, Schema, - ValueType, }; use mentat_query::{ diff --git a/query-projector/src/aggregates.rs b/query-projector/src/aggregates.rs index 8fde9b2a..bfe80564 100644 --- a/query-projector/src/aggregates.rs +++ b/query-projector/src/aggregates.rs @@ -8,8 +8,11 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -use mentat_core::{ +use core_traits::{ ValueType, +}; + +use mentat_core::{ ValueTypeSet, }; diff --git a/query-projector/src/binding_tuple.rs b/query-projector/src/binding_tuple.rs index 5af2abd6..02fc94c9 100644 --- a/query-projector/src/binding_tuple.rs +++ b/query-projector/src/binding_tuple.rs @@ -8,7 +8,7 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -use mentat_core::{ +use core_traits::{ Binding, }; diff --git a/query-projector/src/lib.rs b/query-projector/src/lib.rs index 18177f17..da6f28de 100644 --- a/query-projector/src/lib.rs +++ b/query-projector/src/lib.rs @@ -37,11 +37,14 @@ use rusqlite::{ Rows, }; -use mentat_core::{ +use core_traits::{ Binding, - Schema, TypedValue, ValueType, +}; + +use mentat_core::{ + Schema, ValueTypeTag, }; diff --git a/query-projector/src/pull.rs b/query-projector/src/pull.rs index 040acec7..082a46c1 100644 --- a/query-projector/src/pull.rs +++ b/query-projector/src/pull.rs @@ -14,14 +14,14 @@ use std::collections::{ }; use core_traits::{ + Binding, Entid, + StructuredMap, + TypedValue, }; use mentat_core::{ - Binding, Schema, - StructuredMap, - TypedValue, ValueRc, }; diff --git a/query-projector/src/relresult.rs b/query-projector/src/relresult.rs index 80f42458..58937221 100644 --- a/query-projector/src/relresult.rs +++ b/query-projector/src/relresult.rs @@ -8,7 +8,7 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. -use mentat_core::{ +use core_traits::{ Binding, TypedValue, }; diff --git a/query-projector/tests/aggregates.rs b/query-projector/tests/aggregates.rs index e7bc03a1..8b5e37cb 100644 --- a/query-projector/tests/aggregates.rs +++ b/query-projector/tests/aggregates.rs @@ -16,12 +16,12 @@ extern crate mentat_query_projector; use core_traits::{ Entid, + ValueType, }; use mentat_core::{ Attribute, Schema, - ValueType, }; use mentat_query::{ diff --git a/query-pull/src/lib.rs b/query-pull/src/lib.rs index 2442144a..7398b8ef 100644 --- a/query-pull/src/lib.rs +++ b/query-pull/src/lib.rs @@ -82,17 +82,17 @@ use std::iter::{ }; use core_traits::{ + Binding, Entid, + TypedValue, + StructuredMap, }; use mentat_core::{ - Binding, Cloned, HasSchema, Keyword, Schema, - StructuredMap, - TypedValue, ValueRc, }; diff --git a/query-sql/src/lib.rs b/query-sql/src/lib.rs index a22b5cb4..b068b83e 100644 --- a/query-sql/src/lib.rs +++ b/query-sql/src/lib.rs @@ -18,12 +18,12 @@ use std::boxed::Box; use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ SQLTypeAffinity, - TypedValue, - ValueType, }; use mentat_query::{ diff --git a/query-translator/src/lib.rs b/query-translator/src/lib.rs index b91cc258..363e5ca7 100644 --- a/query-translator/src/lib.rs +++ b/query-translator/src/lib.rs @@ -10,6 +10,7 @@ extern crate failure; +extern crate core_traits; extern crate mentat_core; extern crate mentat_query; extern crate mentat_query_algebrizer; diff --git a/query-translator/src/translate.rs b/query-translator/src/translate.rs index 687e3b03..94b03973 100644 --- a/query-translator/src/translate.rs +++ b/query-translator/src/translate.rs @@ -8,13 +8,16 @@ // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. +use core_traits::{ + TypedValue, + ValueType, +}; + use mentat_core::{ Schema, SQLTypeAffinity, SQLValueType, SQLValueTypeSet, - TypedValue, - ValueType, ValueTypeTag, ValueTypeSet, }; diff --git a/query-translator/tests/translate.rs b/query-translator/tests/translate.rs index ae2ba48d..293bed8b 100644 --- a/query-translator/tests/translate.rs +++ b/query-translator/tests/translate.rs @@ -28,13 +28,13 @@ use mentat_query::{ use core_traits::{ Entid, + TypedValue, + ValueType, }; use mentat_core::{ Attribute, Schema, - TypedValue, - ValueType, }; use mentat_query_algebrizer::{ diff --git a/sql/Cargo.toml b/sql/Cargo.toml index 5385a41e..133e2335 100644 --- a/sql/Cargo.toml +++ b/sql/Cargo.toml @@ -12,5 +12,8 @@ ordered-float = "0.5" version = "0.13" features = ["limits"] +[dependencies.core_traits] +path = "../core-traits" + [dependencies.mentat_core] path = "../core" diff --git a/sql/src/lib.rs b/sql/src/lib.rs index 8893c341..3cf59340 100644 --- a/sql/src/lib.rs +++ b/sql/src/lib.rs @@ -13,6 +13,7 @@ extern crate failure; extern crate ordered_float; extern crate rusqlite; +extern crate core_traits; extern crate mentat_core; use std::rc::Rc; @@ -21,9 +22,12 @@ use std::collections::HashMap; use ordered_float::OrderedFloat; +use core_traits::{ + TypedValue, +}; + use mentat_core::{ ToMicros, - TypedValue, ValueRc, }; diff --git a/src/conn.rs b/src/conn.rs index a0c9d93f..86f49bb3 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -48,6 +48,9 @@ use edn::{ pub use core_traits::{ Entid, KnownEntid, + StructuredMap, + TypedValue, + ValueType, }; use mentat_core::{ @@ -55,11 +58,8 @@ use mentat_core::{ HasSchema, Keyword, Schema, - StructuredMap, TxReport, - TypedValue, ValueRc, - ValueType, }; use mentat_db::cache::{ @@ -861,12 +861,15 @@ mod tests { Instant, }; - use mentat_core::{ - CachedAttributes, + use core_traits::{ Binding, TypedValue, }; + use mentat_core::{ + CachedAttributes, + }; + use ::query::{ Variable, }; diff --git a/src/entity_builder.rs b/src/entity_builder.rs index 9ad9d162..6aa0d0f9 100644 --- a/src/entity_builder.rs +++ b/src/entity_builder.rs @@ -68,9 +68,12 @@ use edn::entities::{ ValuePlace, }; +use core_traits::{ + TypedValue, +}; + use mentat_core::{ TxReport, - TypedValue, }; use conn::{ diff --git a/src/errors.rs b/src/errors.rs index cffa3999..eb14341e 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -18,9 +18,12 @@ use rusqlite; use edn; +use core_traits::{ + ValueType, +}; + use mentat_core::{ Attribute, - ValueType, }; use mentat_db; diff --git a/src/lib.rs b/src/lib.rs index eee2df5d..1cd9d336 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,24 +36,24 @@ extern crate mentat_sql; extern crate mentat_tolstoy; pub use core_traits::{ + Binding, Entid, KnownEntid, + StructuredMap, + TypedValue, + ValueType, + now, }; pub use mentat_core::{ Attribute, - Binding, DateTime, HasSchema, Keyword, Schema, - StructuredMap, TxReport, - TypedValue, Utc, Uuid, - ValueType, - now, }; pub use mentat_query::{ diff --git a/src/query.rs b/src/query.rs index ed35ac97..f2f284c9 100644 --- a/src/query.rs +++ b/src/query.rs @@ -14,15 +14,15 @@ use rusqlite::types::ToSql; use std::rc::Rc; use core_traits::{ + Binding, Entid, KnownEntid, + TypedValue, }; use mentat_core::{ - Binding, HasSchema, Schema, - TypedValue, }; use mentat_query_algebrizer::{ diff --git a/src/query_builder.rs b/src/query_builder.rs index 8e0a386b..6012f8d1 100644 --- a/src/query_builder.rs +++ b/src/query_builder.rs @@ -15,15 +15,15 @@ use std::collections::{ pub use core_traits::{ Entid, + Binding, + TypedValue, + ValueType, }; use mentat_core::{ DateTime, Keyword, - Binding, - TypedValue, Utc, - ValueType, }; use ::{ diff --git a/src/store.rs b/src/store.rs index a58a6840..0a10bf1d 100644 --- a/src/store.rs +++ b/src/store.rs @@ -28,13 +28,13 @@ use edn; use core_traits::{ Entid, + StructuredMap, + TypedValue, }; use mentat_core::{ Keyword, - StructuredMap, TxReport, - TypedValue, ValueRc, }; use mentat_db::{ @@ -280,11 +280,14 @@ mod tests { SQLiteAttributeCache, }; + use core_traits::{ + TypedValue, + ValueType, + }; + use mentat_core::{ CachedAttributes, HasSchema, - TypedValue, - ValueType, }; use ::entity_builder::{ diff --git a/tests/pull.rs b/tests/pull.rs index ba8a7570..dac53cd1 100644 --- a/tests/pull.rs +++ b/tests/pull.rs @@ -11,6 +11,7 @@ #[macro_use] extern crate mentat; extern crate mentat_core; +extern crate core_traits; extern crate mentat_query_pull; use std::collections::{ @@ -23,10 +24,13 @@ use std::path::{ PathBuf, }; -// TODO: re-export from Mentat. -use mentat_core::{ +use core_traits::{ Binding, StructuredMap, +}; + +// TODO: re-export from Mentat. +use mentat_core::{ ValueRc, }; diff --git a/tests/query.rs b/tests/query.rs index c52d4a74..da45b53d 100644 --- a/tests/query.rs +++ b/tests/query.rs @@ -29,6 +29,7 @@ use chrono::FixedOffset; use core_traits::{ Entid, KnownEntid, + ValueType, }; use mentat_core::{ @@ -36,7 +37,6 @@ use mentat_core::{ HasSchema, Utc, Uuid, - ValueType, ValueTypeSet, }; diff --git a/tests/tolstoy.rs b/tests/tolstoy.rs index 032b1113..dc5ccab9 100644 --- a/tests/tolstoy.rs +++ b/tests/tolstoy.rs @@ -9,7 +9,6 @@ // specific language governing permissions and limitations under the License. extern crate mentat; -extern crate mentat_core; extern crate core_traits; #[cfg(feature = "syncable")] @@ -30,8 +29,6 @@ mod tests { use mentat_tolstoy::errors::Result; use core_traits::{ Entid, - }; - use mentat_core::{ TypedValue, ValueType, }; diff --git a/tolstoy/src/tx_processor.rs b/tolstoy/src/tx_processor.rs index 808cce8c..d602de70 100644 --- a/tolstoy/src/tx_processor.rs +++ b/tolstoy/src/tx_processor.rs @@ -21,9 +21,6 @@ use mentat_db::{ use core_traits::{ Entid, -}; - -use mentat_core::{ TypedValue, }; diff --git a/tools/cli/Cargo.toml b/tools/cli/Cargo.toml index 126d1a75..d639f899 100644 --- a/tools/cli/Cargo.toml +++ b/tools/cli/Cargo.toml @@ -46,8 +46,8 @@ path = "../../edn" [dependencies.mentat_query] path = "../../query" -[dependencies.mentat_core] -path = "../../core" +[dependencies.core_traits] +path = "../../core-traits" [dependencies.mentat_db] path = "../../db" diff --git a/tools/cli/src/mentat_cli/lib.rs b/tools/cli/src/mentat_cli/lib.rs index 0a47272b..ccb9d50a 100644 --- a/tools/cli/src/mentat_cli/lib.rs +++ b/tools/cli/src/mentat_cli/lib.rs @@ -31,7 +31,7 @@ extern crate time; extern crate mentat; extern crate edn; extern crate mentat_query; -extern crate mentat_core; +extern crate core_traits; extern crate mentat_db; use getopts::Options; diff --git a/tools/cli/src/mentat_cli/repl.rs b/tools/cli/src/mentat_cli/repl.rs index 2a75440c..8266d3dc 100644 --- a/tools/cli/src/mentat_cli/repl.rs +++ b/tools/cli/src/mentat_cli/repl.rs @@ -30,7 +30,7 @@ use time::{ PreciseTime, }; -use mentat_core::{ +use core_traits::{ StructuredMap, };