Pre: Move core/types.rs into core_traits
This commit is contained in:
parent
a57ba5d79f
commit
d0214fad7d
71 changed files with 1033 additions and 954 deletions
|
@ -7,5 +7,16 @@ workspace = ".."
|
||||||
name = "core_traits"
|
name = "core_traits"
|
||||||
path = "lib.rs"
|
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]
|
[dependencies.edn]
|
||||||
path = "../edn"
|
path = "../edn"
|
||||||
|
features = ["serde_support"]
|
||||||
|
|
|
@ -8,7 +8,61 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// 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;
|
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::{
|
use edn::entities::{
|
||||||
AttributePlace,
|
AttributePlace,
|
||||||
|
@ -18,6 +72,8 @@ use edn::entities::{
|
||||||
TransactableValueMarker,
|
TransactableValueMarker,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod values;
|
||||||
|
|
||||||
/// Represents one entid in the entid space.
|
/// Represents one entid in the entid space.
|
||||||
///
|
///
|
||||||
/// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite
|
/// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite
|
||||||
|
@ -53,3 +109,752 @@ impl<V: TransactableValueMarker> Into<ValuePlace<V>> for KnownEntid {
|
||||||
ValuePlace::Entid(EntidOrIdent::Entid(self.0))
|
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<ValueType> {
|
||||||
|
// 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<Self> {
|
||||||
|
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<f64>),
|
||||||
|
Instant(DateTime<Utc>), // Use `into()` to ensure truncation.
|
||||||
|
// TODO: &str throughout?
|
||||||
|
String(ValueRc<String>),
|
||||||
|
Keyword(ValueRc<Keyword>),
|
||||||
|
Uuid(Uuid), // It's only 128 bits, so this should be acceptable to clone.
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<KnownEntid> 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<T: Into<Option<ValueType>>>(&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<S: AsRef<str>, T: AsRef<str>>(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: AsRef<str>>(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::<Utc>::from_micros(micros).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_known_entid(self) -> Option<KnownEntid> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Ref(v) => Some(KnownEntid(v)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_entid(self) -> Option<Entid> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Ref(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_kw(self) -> Option<ValueRc<Keyword>> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Keyword(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_boolean(self) -> Option<bool> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Boolean(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_long(self) -> Option<i64> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Long(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_double(self) -> Option<f64> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Double(v) => Some(v.into_inner()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_instant(self) -> Option<DateTime<Utc>> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Instant(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_timestamp(self) -> Option<i64> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Instant(v) => Some(v.timestamp()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_string(self) -> Option<ValueRc<String>> {
|
||||||
|
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<Uuid> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Uuid(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_uuid_string(self) -> Option<String> {
|
||||||
|
match self {
|
||||||
|
TypedValue::Uuid(v) => Some(v.hyphenated().to_string()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't do From<i64> or From<Entid> 'cos it's ambiguous.
|
||||||
|
|
||||||
|
impl From<bool> 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<DateTime<Utc>> for TypedValue {
|
||||||
|
fn from(value: DateTime<Utc>) -> TypedValue {
|
||||||
|
TypedValue::Instant(value.microsecond_precision())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Uuid> 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<Arc<String>> for TypedValue {
|
||||||
|
fn from(value: Arc<String>) -> TypedValue {
|
||||||
|
TypedValue::String(ValueRc::from_arc(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Rc<String>> for TypedValue {
|
||||||
|
fn from(value: Rc<String>) -> TypedValue {
|
||||||
|
TypedValue::String(ValueRc::from_rc(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Box<String>> for TypedValue {
|
||||||
|
fn from(value: Box<String>) -> TypedValue {
|
||||||
|
TypedValue::String(ValueRc::new(*value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for TypedValue {
|
||||||
|
fn from(value: String) -> TypedValue {
|
||||||
|
TypedValue::String(ValueRc::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Arc<Keyword>> for TypedValue {
|
||||||
|
fn from(value: Arc<Keyword>) -> TypedValue {
|
||||||
|
TypedValue::Keyword(ValueRc::from_arc(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Rc<Keyword>> for TypedValue {
|
||||||
|
fn from(value: Rc<Keyword>) -> TypedValue {
|
||||||
|
TypedValue::Keyword(ValueRc::from_rc(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Keyword> for TypedValue {
|
||||||
|
fn from(value: Keyword) -> TypedValue {
|
||||||
|
TypedValue::Keyword(ValueRc::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u32> for TypedValue {
|
||||||
|
fn from(value: u32) -> TypedValue {
|
||||||
|
TypedValue::Long(value as i64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<i32> for TypedValue {
|
||||||
|
fn from(value: i32) -> TypedValue {
|
||||||
|
TypedValue::Long(value as i64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<f64> 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<Utc> {
|
||||||
|
fn microsecond_precision(self) -> DateTime<Utc> {
|
||||||
|
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<Vec<Binding>>),
|
||||||
|
Map(ValueRc<StructuredMap>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for Binding where T: Into<TypedValue> {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Binding::Scalar(value.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StructuredMap> for Binding {
|
||||||
|
fn from(value: StructuredMap) -> Self {
|
||||||
|
Binding::Map(ValueRc::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<Binding>> for Binding {
|
||||||
|
fn from(value: Vec<Binding>) -> Self {
|
||||||
|
Binding::Vec(ValueRc::new(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Binding {
|
||||||
|
pub fn into_scalar(self) -> Option<TypedValue> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_vec(self) -> Option<ValueRc<Vec<Binding>>> {
|
||||||
|
match self {
|
||||||
|
Binding::Vec(v) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_map(self) -> Option<ValueRc<StructuredMap>> {
|
||||||
|
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<Binding>> {
|
||||||
|
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<ValueRc<Keyword>, Binding>);
|
||||||
|
|
||||||
|
impl Deref for StructuredMap {
|
||||||
|
type Target = IndexMap<ValueRc<Keyword>, Binding>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StructuredMap {
|
||||||
|
pub fn insert<N, B>(&mut self, name: N, value: B) where N: Into<ValueRc<Keyword>>, B: Into<Binding> {
|
||||||
|
self.0.insert(name.into(), value.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IndexMap<ValueRc<Keyword>, Binding>> for StructuredMap {
|
||||||
|
fn from(src: IndexMap<ValueRc<Keyword>, Binding>) -> Self {
|
||||||
|
StructuredMap(src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostly for testing.
|
||||||
|
impl<T> From<Vec<(Keyword, T)>> for StructuredMap where T: Into<Binding> {
|
||||||
|
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<T: Into<Option<ValueType>>>(&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<ValueType> {
|
||||||
|
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> {
|
||||||
|
Utc::now().microsecond_precision()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Binding {
|
||||||
|
pub fn into_known_entid(self) -> Option<KnownEntid> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Ref(v)) => Some(KnownEntid(v)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_entid(self) -> Option<Entid> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Ref(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_kw(self) -> Option<ValueRc<Keyword>> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Keyword(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_boolean(self) -> Option<bool> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Boolean(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_long(self) -> Option<i64> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Long(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_double(self) -> Option<f64> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Double(v)) => Some(v.into_inner()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_instant(self) -> Option<DateTime<Utc>> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Instant(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_timestamp(self) -> Option<i64> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Instant(v)) => Some(v.timestamp()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_string(self) -> Option<ValueRc<String>> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::String(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_uuid(self) -> Option<Uuid> {
|
||||||
|
match self {
|
||||||
|
Binding::Scalar(TypedValue::Uuid(v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_uuid_string(self) -> Option<String> {
|
||||||
|
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<Keyword>> {
|
||||||
|
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<Utc>> {
|
||||||
|
match self {
|
||||||
|
&Binding::Scalar(TypedValue::Instant(ref v)) => Some(v),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_string(&self) -> Option<&ValueRc<String>> {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
|
@ -8,11 +8,8 @@ chrono = { version = "0.4", features = ["serde"] }
|
||||||
enum-set = "0.0.7"
|
enum-set = "0.0.7"
|
||||||
failure = "0.1.1"
|
failure = "0.1.1"
|
||||||
indexmap = "1"
|
indexmap = "1"
|
||||||
lazy_static = "0.2"
|
|
||||||
ordered-float = { version = "0.5", features = ["serde"] }
|
ordered-float = { version = "0.5", features = ["serde"] }
|
||||||
uuid = { version = "0.5", features = ["v4", "serde"] }
|
uuid = { version = "0.5", features = ["v4", "serde"] }
|
||||||
serde = { version = "1.0", features = ["rc"] }
|
|
||||||
serde_derive = "1.0"
|
|
||||||
|
|
||||||
[dependencies.core_traits]
|
[dependencies.core_traits]
|
||||||
path = "../core-traits"
|
path = "../core-traits"
|
||||||
|
|
|
@ -16,11 +16,11 @@ use std::collections::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ::{
|
use ::{
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait CachedAttributes {
|
pub trait CachedAttributes {
|
||||||
|
|
|
@ -14,24 +14,18 @@ extern crate failure;
|
||||||
extern crate indexmap;
|
extern crate indexmap;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
extern crate serde;
|
|
||||||
|
|
||||||
extern crate core_traits;
|
extern crate core_traits;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
|
|
||||||
extern crate edn;
|
extern crate edn;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
values,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod values;
|
|
||||||
mod cache;
|
mod cache;
|
||||||
|
|
||||||
use std::collections::{
|
use std::collections::{
|
||||||
|
@ -76,12 +70,7 @@ pub use tx_report::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use types::{
|
pub use types::{
|
||||||
Binding,
|
|
||||||
StructuredMap,
|
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeTag,
|
ValueTypeTag,
|
||||||
now,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use value_type_set::{
|
pub use value_type_set::{
|
||||||
|
@ -106,7 +95,9 @@ pub enum AttributeBitFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod attribute {
|
pub mod attribute {
|
||||||
use TypedValue;
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||||
pub enum Unique {
|
pub enum Unique {
|
||||||
|
@ -423,6 +414,10 @@ mod test {
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
|
fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
|
||||||
schema.entid_map.insert(e, i.clone());
|
schema.entid_map.insert(e, i.clone());
|
||||||
schema.ident_map.insert(i, e);
|
schema.ident_map.insert(i, e);
|
||||||
|
|
|
@ -12,8 +12,11 @@ use std::collections::{
|
||||||
BTreeSet,
|
BTreeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
use types::{
|
use core_traits::{
|
||||||
ValueType,
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
|
use types::{
|
||||||
ValueTypeTag,
|
ValueTypeTag,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +73,10 @@ impl SQLValueType for ValueType {
|
||||||
/// example, `1` is how we encode `true`.
|
/// 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(1493399581314));
|
||||||
/// assert!(!ValueType::Instant.accommodates_integer(1493399581314000));
|
/// assert!(!ValueType::Instant.accommodates_integer(1493399581314000));
|
||||||
/// assert!(ValueType::Boolean.accommodates_integer(1));
|
/// assert!(ValueType::Boolean.accommodates_integer(1));
|
||||||
|
|
|
@ -8,814 +8,4 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// 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<KnownEntid> 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;
|
pub type ValueTypeTag = i32;
|
||||||
|
|
||||||
impl ValueType {
|
|
||||||
pub fn all_enums() -> EnumSet<ValueType> {
|
|
||||||
// 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<Self> {
|
|
||||||
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<f64>),
|
|
||||||
Instant(DateTime<Utc>), // Use `into()` to ensure truncation.
|
|
||||||
// TODO: &str throughout?
|
|
||||||
String(ValueRc<String>),
|
|
||||||
Keyword(ValueRc<Keyword>),
|
|
||||||
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<Vec<Binding>>),
|
|
||||||
Map(ValueRc<StructuredMap>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<T> for Binding where T: Into<TypedValue> {
|
|
||||||
fn from(value: T) -> Self {
|
|
||||||
Binding::Scalar(value.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StructuredMap> for Binding {
|
|
||||||
fn from(value: StructuredMap) -> Self {
|
|
||||||
Binding::Map(ValueRc::new(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<Binding>> for Binding {
|
|
||||||
fn from(value: Vec<Binding>) -> Self {
|
|
||||||
Binding::Vec(ValueRc::new(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Binding {
|
|
||||||
pub fn into_scalar(self) -> Option<TypedValue> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_vec(self) -> Option<ValueRc<Vec<Binding>>> {
|
|
||||||
match self {
|
|
||||||
Binding::Vec(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_map(self) -> Option<ValueRc<StructuredMap>> {
|
|
||||||
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<Binding>> {
|
|
||||||
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<ValueRc<Keyword>, Binding>);
|
|
||||||
|
|
||||||
impl Deref for StructuredMap {
|
|
||||||
type Target = IndexMap<ValueRc<Keyword>, Binding>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StructuredMap {
|
|
||||||
pub fn insert<N, B>(&mut self, name: N, value: B) where N: Into<ValueRc<Keyword>>, B: Into<Binding> {
|
|
||||||
self.0.insert(name.into(), value.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<IndexMap<ValueRc<Keyword>, Binding>> for StructuredMap {
|
|
||||||
fn from(src: IndexMap<ValueRc<Keyword>, Binding>) -> Self {
|
|
||||||
StructuredMap(src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mostly for testing.
|
|
||||||
impl<T> From<Vec<(Keyword, T)>> for StructuredMap where T: Into<Binding> {
|
|
||||||
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<T: Into<Option<ValueType>>>(&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<ValueType> {
|
|
||||||
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<T: Into<Option<ValueType>>>(&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<S: AsRef<str>, T: AsRef<str>>(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: AsRef<str>>(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::<Utc>::from_micros(micros).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait MicrosecondPrecision {
|
|
||||||
/// Truncate the provided `DateTime` to microsecond precision.
|
|
||||||
fn microsecond_precision(self) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MicrosecondPrecision for DateTime<Utc> {
|
|
||||||
fn microsecond_precision(self) -> DateTime<Utc> {
|
|
||||||
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> {
|
|
||||||
Utc::now().microsecond_precision()
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't do From<i64> or From<Entid> 'cos it's ambiguous.
|
|
||||||
|
|
||||||
impl From<bool> 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<DateTime<Utc>> for TypedValue {
|
|
||||||
fn from(value: DateTime<Utc>) -> TypedValue {
|
|
||||||
TypedValue::Instant(value.microsecond_precision())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Uuid> 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<Arc<String>> for TypedValue {
|
|
||||||
fn from(value: Arc<String>) -> TypedValue {
|
|
||||||
TypedValue::String(ValueRc::from_arc(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Rc<String>> for TypedValue {
|
|
||||||
fn from(value: Rc<String>) -> TypedValue {
|
|
||||||
TypedValue::String(ValueRc::from_rc(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Box<String>> for TypedValue {
|
|
||||||
fn from(value: Box<String>) -> TypedValue {
|
|
||||||
TypedValue::String(ValueRc::new(*value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for TypedValue {
|
|
||||||
fn from(value: String) -> TypedValue {
|
|
||||||
TypedValue::String(ValueRc::new(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Arc<Keyword>> for TypedValue {
|
|
||||||
fn from(value: Arc<Keyword>) -> TypedValue {
|
|
||||||
TypedValue::Keyword(ValueRc::from_arc(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Rc<Keyword>> for TypedValue {
|
|
||||||
fn from(value: Rc<Keyword>) -> TypedValue {
|
|
||||||
TypedValue::Keyword(ValueRc::from_rc(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Keyword> for TypedValue {
|
|
||||||
fn from(value: Keyword) -> TypedValue {
|
|
||||||
TypedValue::Keyword(ValueRc::new(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u32> for TypedValue {
|
|
||||||
fn from(value: u32) -> TypedValue {
|
|
||||||
TypedValue::Long(value as i64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<i32> for TypedValue {
|
|
||||||
fn from(value: i32) -> TypedValue {
|
|
||||||
TypedValue::Long(value as i64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<f64> for TypedValue {
|
|
||||||
fn from(value: f64) -> TypedValue {
|
|
||||||
TypedValue::Double(OrderedFloat(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypedValue {
|
|
||||||
pub fn into_known_entid(self) -> Option<KnownEntid> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Ref(v) => Some(KnownEntid(v)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_entid(self) -> Option<Entid> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Ref(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_kw(self) -> Option<ValueRc<Keyword>> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Keyword(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_boolean(self) -> Option<bool> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Boolean(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_long(self) -> Option<i64> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Long(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_double(self) -> Option<f64> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Double(v) => Some(v.into_inner()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_instant(self) -> Option<DateTime<Utc>> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Instant(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_timestamp(self) -> Option<i64> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Instant(v) => Some(v.timestamp()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_string(self) -> Option<ValueRc<String>> {
|
|
||||||
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<Uuid> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Uuid(v) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_uuid_string(self) -> Option<String> {
|
|
||||||
match self {
|
|
||||||
TypedValue::Uuid(v) => Some(v.hyphenated().to_string()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Binding {
|
|
||||||
pub fn into_known_entid(self) -> Option<KnownEntid> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Ref(v)) => Some(KnownEntid(v)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_entid(self) -> Option<Entid> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Ref(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_kw(self) -> Option<ValueRc<Keyword>> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Keyword(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_boolean(self) -> Option<bool> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Boolean(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_long(self) -> Option<i64> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Long(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_double(self) -> Option<f64> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Double(v)) => Some(v.into_inner()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_instant(self) -> Option<DateTime<Utc>> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Instant(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_timestamp(self) -> Option<i64> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Instant(v)) => Some(v.timestamp()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_string(self) -> Option<ValueRc<String>> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::String(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_uuid(self) -> Option<Uuid> {
|
|
||||||
match self {
|
|
||||||
Binding::Scalar(TypedValue::Uuid(v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_uuid_string(self) -> Option<String> {
|
|
||||||
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<Keyword>> {
|
|
||||||
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<Utc>> {
|
|
||||||
match self {
|
|
||||||
&Binding::Scalar(TypedValue::Instant(ref v)) => Some(v),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_string(&self) -> Option<&ValueRc<String>> {
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use ::enum_set::{
|
||||||
EnumSet,
|
EnumSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ::types::{
|
use core_traits::{
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,15 @@ use edn::symbols;
|
||||||
use entids;
|
use entids;
|
||||||
use db::TypedSQLValue;
|
use db::TypedSQLValue;
|
||||||
use edn::entities::Entity;
|
use edn::entities::Entity;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
IdentMap,
|
IdentMap,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
values,
|
|
||||||
};
|
};
|
||||||
use schema::SchemaBuilding;
|
use schema::SchemaBuilding;
|
||||||
use types::{Partition, PartitionMap};
|
use types::{Partition, PartitionMap};
|
||||||
|
|
|
@ -79,15 +79,15 @@ use failure::{
|
||||||
use rusqlite;
|
use rusqlite;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
|
Binding,
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Binding,
|
|
||||||
CachedAttributes,
|
CachedAttributes,
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
UpdateableCache,
|
UpdateableCache,
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,6 +43,8 @@ use entids;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
|
@ -53,9 +55,7 @@ use mentat_core::{
|
||||||
IdentMap,
|
IdentMap,
|
||||||
Schema,
|
Schema,
|
||||||
AttributeMap,
|
AttributeMap,
|
||||||
TypedValue,
|
|
||||||
ToMicros,
|
ToMicros,
|
||||||
ValueType,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -69,14 +69,14 @@ use errors::Result;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
HasSchema,
|
HasSchema,
|
||||||
SQLValueType,
|
SQLValueType,
|
||||||
TxReport,
|
TxReport,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
use edn::{
|
use edn::{
|
||||||
InternSet,
|
InternSet,
|
||||||
|
|
|
@ -30,9 +30,6 @@ use edn::entities::{
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
};
|
|
||||||
|
|
||||||
use types::{
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,8 @@ use std::collections::{
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::util::Either;
|
use mentat_core::util::Either;
|
||||||
|
@ -53,8 +55,6 @@ use types::{
|
||||||
AVPair,
|
AVPair,
|
||||||
Schema,
|
Schema,
|
||||||
TransactableValue,
|
TransactableValue,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl TransactableValue for ValueAndSpan {
|
impl TransactableValue for ValueAndSpan {
|
||||||
|
|
|
@ -41,14 +41,14 @@ use errors::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
attribute,
|
attribute,
|
||||||
Schema,
|
Schema,
|
||||||
AttributeMap,
|
AttributeMap,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use schema::{
|
use schema::{
|
||||||
|
|
|
@ -21,6 +21,8 @@ use edn::symbols;
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
|
@ -31,8 +33,6 @@ use mentat_core::{
|
||||||
IdentMap,
|
IdentMap,
|
||||||
Schema,
|
Schema,
|
||||||
AttributeMap,
|
AttributeMap,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
use metadata;
|
use metadata;
|
||||||
use metadata::{
|
use metadata::{
|
||||||
|
|
|
@ -20,11 +20,11 @@ use errors::{
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use edn::{
|
use edn::{
|
||||||
|
|
|
@ -92,6 +92,9 @@ use mentat_core::util::Either;
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
|
now,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
|
@ -100,7 +103,6 @@ use mentat_core::{
|
||||||
TxReport,
|
TxReport,
|
||||||
Utc,
|
Utc,
|
||||||
attribute,
|
attribute,
|
||||||
now,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use edn::entities as entmod;
|
use edn::entities as entmod;
|
||||||
|
@ -122,8 +124,6 @@ use types::{
|
||||||
Attribute,
|
Attribute,
|
||||||
PartitionMap,
|
PartitionMap,
|
||||||
TransactableValue,
|
TransactableValue,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
use upsert_resolution::{
|
use upsert_resolution::{
|
||||||
FinalPopulations,
|
FinalPopulations,
|
||||||
|
|
|
@ -15,9 +15,6 @@ use std::collections::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
};
|
|
||||||
|
|
||||||
use mentat_core::{
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,11 +28,11 @@ use indexmap::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use edn::entities::{
|
use edn::entities::{
|
||||||
|
|
|
@ -28,6 +28,8 @@ extern crate mentat_core;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::mentat_core::{
|
pub use self::mentat_core::{
|
||||||
|
@ -35,9 +37,7 @@ pub use self::mentat_core::{
|
||||||
AttributeBitFlags,
|
AttributeBitFlags,
|
||||||
DateTime,
|
DateTime,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
Utc,
|
Utc,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use edn::entities::{
|
use edn::entities::{
|
||||||
|
|
|
@ -42,13 +42,13 @@ use mentat_core::util::Either::*;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
attribute,
|
attribute,
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
use edn::entities::OpType;
|
use edn::entities::OpType;
|
||||||
use schema::SchemaBuilding;
|
use schema::SchemaBuilding;
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use edn::entities::{
|
use edn::entities::{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
extern crate edn;
|
extern crate edn;
|
||||||
extern crate mentat_core;
|
extern crate core_traits;
|
||||||
extern crate mentat_db;
|
extern crate mentat_db;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
extern crate rusqlite;
|
extern crate rusqlite;
|
||||||
|
@ -18,7 +18,10 @@ use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use edn::symbols;
|
use edn::symbols;
|
||||||
|
|
||||||
use mentat_core::{TypedValue, ValueType};
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
use mentat_db::db::TypedSQLValue;
|
use mentat_db::db::TypedSQLValue;
|
||||||
|
|
||||||
// It's not possible to test to_sql_value_pair since rusqlite::ToSqlOutput doesn't implement
|
// It's not possible to test to_sql_value_pair since rusqlite::ToSqlOutput doesn't implement
|
||||||
|
|
|
@ -8,12 +8,15 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Schema,
|
Schema,
|
||||||
SQLValueType,
|
SQLValueType,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
HasSchema,
|
HasSchema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::util::Either;
|
use mentat_core::util::Either;
|
||||||
|
@ -261,10 +264,13 @@ impl ConjoiningClauses {
|
||||||
mod testing {
|
mod testing {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -321,9 +324,12 @@ impl ConjoiningClauses {
|
||||||
mod testing {
|
mod testing {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -28,6 +28,8 @@ use std::fmt::{
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
|
@ -35,8 +37,6 @@ use mentat_core::{
|
||||||
Cloned,
|
Cloned,
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -90,11 +90,14 @@ mod testing {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -753,11 +753,14 @@ fn union_types(into: &mut BTreeMap<Variable, ValueTypeSet>,
|
||||||
mod testing {
|
mod testing {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Cloned,
|
Cloned,
|
||||||
HasSchema,
|
HasSchema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,11 +191,13 @@ mod testing {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use mentat_core::attribute::Unique;
|
use mentat_core::attribute::Unique;
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
Attribute,
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
use mentat_core::{
|
||||||
|
Attribute,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
FnArg,
|
FnArg,
|
||||||
|
|
|
@ -8,11 +8,14 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -248,12 +248,15 @@ impl ConjoiningClauses {
|
||||||
mod testing {
|
mod testing {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
Schema,
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use mentat_core::{
|
||||||
|
Schema,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
Binding,
|
Binding,
|
||||||
FnArg,
|
FnArg,
|
||||||
|
|
|
@ -12,9 +12,12 @@ extern crate mentat_query;
|
||||||
|
|
||||||
use std; // To refer to std::result::Result.
|
use std; // To refer to std::result::Result.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
EdnParseError,
|
EdnParseError,
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,13 @@ mod clauses;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
CachedAttributes,
|
CachedAttributes,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
parse_query,
|
parse_query,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,12 @@ use std::fmt::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
TypedValue,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,13 @@ extern crate mentat_query_algebrizer;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -17,11 +17,14 @@ mod utils;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -15,13 +15,16 @@ extern crate mentat_query_algebrizer;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
DateTime,
|
DateTime,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
Utc,
|
Utc,
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
extern crate mentat_core;
|
|
||||||
extern crate core_traits;
|
extern crate core_traits;
|
||||||
|
extern crate mentat_core;
|
||||||
extern crate mentat_query;
|
extern crate mentat_query;
|
||||||
extern crate mentat_query_algebrizer;
|
extern crate mentat_query_algebrizer;
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@ use utils::{
|
||||||
bails,
|
bails,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query_algebrizer::Known;
|
use mentat_query_algebrizer::Known;
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -8,8 +8,11 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
ValueType,
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
|
use mentat_core::{
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
Binding,
|
Binding,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,14 @@ use rusqlite::{
|
||||||
Rows,
|
Rows,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
Binding,
|
Binding,
|
||||||
Schema,
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
|
use mentat_core::{
|
||||||
|
Schema,
|
||||||
ValueTypeTag,
|
ValueTypeTag,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,14 @@ use std::collections::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
|
Binding,
|
||||||
Entid,
|
Entid,
|
||||||
|
StructuredMap,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Binding,
|
|
||||||
Schema,
|
Schema,
|
||||||
StructuredMap,
|
|
||||||
TypedValue,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
Binding,
|
Binding,
|
||||||
TypedValue,
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,12 +16,12 @@ extern crate mentat_query_projector;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -82,17 +82,17 @@ use std::iter::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
|
Binding,
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
StructuredMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Binding,
|
|
||||||
Cloned,
|
Cloned,
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Keyword,
|
Keyword,
|
||||||
Schema,
|
Schema,
|
||||||
StructuredMap,
|
|
||||||
TypedValue,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ use std::boxed::Box;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
SQLTypeAffinity,
|
SQLTypeAffinity,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query::{
|
use mentat_query::{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
|
|
||||||
|
extern crate core_traits;
|
||||||
extern crate mentat_core;
|
extern crate mentat_core;
|
||||||
extern crate mentat_query;
|
extern crate mentat_query;
|
||||||
extern crate mentat_query_algebrizer;
|
extern crate mentat_query_algebrizer;
|
||||||
|
|
|
@ -8,13 +8,16 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Schema,
|
Schema,
|
||||||
SQLTypeAffinity,
|
SQLTypeAffinity,
|
||||||
SQLValueType,
|
SQLValueType,
|
||||||
SQLValueTypeSet,
|
SQLValueTypeSet,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
ValueTypeTag,
|
ValueTypeTag,
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,13 +28,13 @@ use mentat_query::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query_algebrizer::{
|
use mentat_query_algebrizer::{
|
||||||
|
|
|
@ -12,5 +12,8 @@ ordered-float = "0.5"
|
||||||
version = "0.13"
|
version = "0.13"
|
||||||
features = ["limits"]
|
features = ["limits"]
|
||||||
|
|
||||||
|
[dependencies.core_traits]
|
||||||
|
path = "../core-traits"
|
||||||
|
|
||||||
[dependencies.mentat_core]
|
[dependencies.mentat_core]
|
||||||
path = "../core"
|
path = "../core"
|
||||||
|
|
|
@ -13,6 +13,7 @@ extern crate failure;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
extern crate rusqlite;
|
extern crate rusqlite;
|
||||||
|
|
||||||
|
extern crate core_traits;
|
||||||
extern crate mentat_core;
|
extern crate mentat_core;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -21,9 +22,12 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
ToMicros,
|
ToMicros,
|
||||||
TypedValue,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
src/conn.rs
13
src/conn.rs
|
@ -48,6 +48,9 @@ use edn::{
|
||||||
pub use core_traits::{
|
pub use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
StructuredMap,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
|
@ -55,11 +58,8 @@ use mentat_core::{
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Keyword,
|
Keyword,
|
||||||
Schema,
|
Schema,
|
||||||
StructuredMap,
|
|
||||||
TxReport,
|
TxReport,
|
||||||
TypedValue,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_db::cache::{
|
use mentat_db::cache::{
|
||||||
|
@ -861,12 +861,15 @@ mod tests {
|
||||||
Instant,
|
Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
CachedAttributes,
|
|
||||||
Binding,
|
Binding,
|
||||||
TypedValue,
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use mentat_core::{
|
||||||
|
CachedAttributes,
|
||||||
|
};
|
||||||
|
|
||||||
use ::query::{
|
use ::query::{
|
||||||
Variable,
|
Variable,
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,9 +68,12 @@ use edn::entities::{
|
||||||
ValuePlace,
|
ValuePlace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
TxReport,
|
TxReport,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use conn::{
|
use conn::{
|
||||||
|
|
|
@ -18,9 +18,12 @@ use rusqlite;
|
||||||
|
|
||||||
use edn;
|
use edn;
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_db;
|
use mentat_db;
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -36,24 +36,24 @@ extern crate mentat_sql;
|
||||||
extern crate mentat_tolstoy;
|
extern crate mentat_tolstoy;
|
||||||
|
|
||||||
pub use core_traits::{
|
pub use core_traits::{
|
||||||
|
Binding,
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
StructuredMap,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
|
now,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use mentat_core::{
|
pub use mentat_core::{
|
||||||
Attribute,
|
Attribute,
|
||||||
Binding,
|
|
||||||
DateTime,
|
DateTime,
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Keyword,
|
Keyword,
|
||||||
Schema,
|
Schema,
|
||||||
StructuredMap,
|
|
||||||
TxReport,
|
TxReport,
|
||||||
TypedValue,
|
|
||||||
Utc,
|
Utc,
|
||||||
Uuid,
|
Uuid,
|
||||||
ValueType,
|
|
||||||
now,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use mentat_query::{
|
pub use mentat_query::{
|
||||||
|
|
|
@ -14,15 +14,15 @@ use rusqlite::types::ToSql;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
|
Binding,
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Binding,
|
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Schema,
|
Schema,
|
||||||
TypedValue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_query_algebrizer::{
|
use mentat_query_algebrizer::{
|
||||||
|
|
|
@ -15,15 +15,15 @@ use std::collections::{
|
||||||
|
|
||||||
pub use core_traits::{
|
pub use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
Binding,
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
DateTime,
|
DateTime,
|
||||||
Keyword,
|
Keyword,
|
||||||
Binding,
|
|
||||||
TypedValue,
|
|
||||||
Utc,
|
Utc,
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ::{
|
use ::{
|
||||||
|
|
11
src/store.rs
11
src/store.rs
|
@ -28,13 +28,13 @@ use edn;
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
|
StructuredMap,
|
||||||
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
Keyword,
|
Keyword,
|
||||||
StructuredMap,
|
|
||||||
TxReport,
|
TxReport,
|
||||||
TypedValue,
|
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
use mentat_db::{
|
use mentat_db::{
|
||||||
|
@ -280,11 +280,14 @@ mod tests {
|
||||||
SQLiteAttributeCache,
|
SQLiteAttributeCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use core_traits::{
|
||||||
|
TypedValue,
|
||||||
|
ValueType,
|
||||||
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
CachedAttributes,
|
CachedAttributes,
|
||||||
HasSchema,
|
HasSchema,
|
||||||
TypedValue,
|
|
||||||
ValueType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ::entity_builder::{
|
use ::entity_builder::{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate mentat;
|
extern crate mentat;
|
||||||
extern crate mentat_core;
|
extern crate mentat_core;
|
||||||
|
extern crate core_traits;
|
||||||
extern crate mentat_query_pull;
|
extern crate mentat_query_pull;
|
||||||
|
|
||||||
use std::collections::{
|
use std::collections::{
|
||||||
|
@ -23,10 +24,13 @@ use std::path::{
|
||||||
PathBuf,
|
PathBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: re-export from Mentat.
|
use core_traits::{
|
||||||
use mentat_core::{
|
|
||||||
Binding,
|
Binding,
|
||||||
StructuredMap,
|
StructuredMap,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: re-export from Mentat.
|
||||||
|
use mentat_core::{
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ use chrono::FixedOffset;
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
KnownEntid,
|
KnownEntid,
|
||||||
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use mentat_core::{
|
||||||
|
@ -36,7 +37,6 @@ use mentat_core::{
|
||||||
HasSchema,
|
HasSchema,
|
||||||
Utc,
|
Utc,
|
||||||
Uuid,
|
Uuid,
|
||||||
ValueType,
|
|
||||||
ValueTypeSet,
|
ValueTypeSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
extern crate mentat;
|
extern crate mentat;
|
||||||
extern crate mentat_core;
|
|
||||||
extern crate core_traits;
|
extern crate core_traits;
|
||||||
|
|
||||||
#[cfg(feature = "syncable")]
|
#[cfg(feature = "syncable")]
|
||||||
|
@ -30,8 +29,6 @@ mod tests {
|
||||||
use mentat_tolstoy::errors::Result;
|
use mentat_tolstoy::errors::Result;
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
};
|
|
||||||
use mentat_core::{
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
ValueType,
|
ValueType,
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,9 +21,6 @@ use mentat_db::{
|
||||||
|
|
||||||
use core_traits::{
|
use core_traits::{
|
||||||
Entid,
|
Entid,
|
||||||
};
|
|
||||||
|
|
||||||
use mentat_core::{
|
|
||||||
TypedValue,
|
TypedValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ path = "../../edn"
|
||||||
[dependencies.mentat_query]
|
[dependencies.mentat_query]
|
||||||
path = "../../query"
|
path = "../../query"
|
||||||
|
|
||||||
[dependencies.mentat_core]
|
[dependencies.core_traits]
|
||||||
path = "../../core"
|
path = "../../core-traits"
|
||||||
|
|
||||||
[dependencies.mentat_db]
|
[dependencies.mentat_db]
|
||||||
path = "../../db"
|
path = "../../db"
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern crate time;
|
||||||
extern crate mentat;
|
extern crate mentat;
|
||||||
extern crate edn;
|
extern crate edn;
|
||||||
extern crate mentat_query;
|
extern crate mentat_query;
|
||||||
extern crate mentat_core;
|
extern crate core_traits;
|
||||||
extern crate mentat_db;
|
extern crate mentat_db;
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
|
|
|
@ -30,7 +30,7 @@ use time::{
|
||||||
PreciseTime,
|
PreciseTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mentat_core::{
|
use core_traits::{
|
||||||
StructuredMap,
|
StructuredMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue