From ad9a1394a3e753213c3eef74bcf7ede98c6e9728 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Mon, 28 May 2018 13:01:14 -0700 Subject: [PATCH] Part 1: Push ValueRc and friends into `edn` crate. This is a pre-requisite for moving the existing `combine`-based parser to use `rust-peg` -- part of the push to use `rust-peg` for all parsing started in https://github.com/mozilla/mentat/pull/681. We need the types for the parsed structure "very early", and the `edn` crate is the earliest such crate. This is an unfortunate destruction of boundaries between parts of the system, but it's the best way we have to achieve this right now. --- core/src/lib.rs | 6 +-- core/src/types.rs | 93 ++------------------------------------ edn/src/lib.rs | 6 +++ edn/src/value_rc.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 93 deletions(-) create mode 100644 edn/src/value_rc.rs diff --git a/core/src/lib.rs b/core/src/lib.rs index bf2446c8..f13341b3 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -38,10 +38,13 @@ pub use chrono::{ }; pub use edn::{ + Cloned, FromMicros, + FromRc, Keyword, ToMicros, Utc, + ValueRc, }; pub use cache::{ @@ -56,15 +59,12 @@ mod sql_types; pub use types::{ Binding, - Cloned, Entid, - FromRc, KnownEntid, StructuredMap, TypedValue, ValueType, ValueTypeTag, - ValueRc, now, }; diff --git a/core/src/types.rs b/core/src/types.rs index ca3b86d4..1ead80b3 100644 --- a/core/src/types.rs +++ b/core/src/types.rs @@ -39,103 +39,16 @@ use ::indexmap::{ use ::edn::{ self, + Cloned, FromMicros, + FromRc, Keyword, Utc, + ValueRc, }; use values; -pub trait FromRc { - fn from_rc(val: Rc) -> Self; - fn from_arc(val: Arc) -> Self; -} - -impl FromRc for Rc where T: Sized + Clone { - fn from_rc(val: Rc) -> Self { - val.clone() - } - - fn from_arc(val: Arc) -> Self { - match ::std::sync::Arc::::try_unwrap(val) { - Ok(v) => Self::new(v), - Err(r) => Self::new(r.cloned()), - } - } -} - -impl FromRc for Arc where T: Sized + Clone { - fn from_rc(val: Rc) -> Self { - match ::std::rc::Rc::::try_unwrap(val) { - Ok(v) => Self::new(v), - Err(r) => Self::new(r.cloned()), - } - } - - fn from_arc(val: Arc) -> Self { - val.clone() - } -} - -impl FromRc for Box where T: Sized + Clone { - fn from_rc(val: Rc) -> Self { - match ::std::rc::Rc::::try_unwrap(val) { - Ok(v) => Self::new(v), - Err(r) => Self::new(r.cloned()), - } - } - - fn from_arc(val: Arc) -> Self { - match ::std::sync::Arc::::try_unwrap(val) { - Ok(v) => Self::new(v), - Err(r) => Self::new(r.cloned()), - } - } -} - -// We do this a lot for errors. -pub trait Cloned { - fn cloned(&self) -> T; - fn to_value_rc(&self) -> ValueRc; -} - -impl Cloned for Rc where T: Sized + Clone { - fn cloned(&self) -> T { - (*self.as_ref()).clone() - } - - fn to_value_rc(&self) -> ValueRc { - ValueRc::from_rc(self.clone()) - } -} - -impl Cloned for Arc where T: Sized + Clone { - fn cloned(&self) -> T { - (*self.as_ref()).clone() - } - - fn to_value_rc(&self) -> ValueRc { - ValueRc::from_arc(self.clone()) - } -} - -impl Cloned for Box where T: Sized + Clone { - fn cloned(&self) -> T { - self.as_ref().clone() - } - - fn to_value_rc(&self) -> ValueRc { - ValueRc::new(self.cloned()) - } -} - -/// -/// This type alias exists to allow us to use different boxing mechanisms for values. -/// This type must implement `FromRc` and `Cloned`, and a `From` implementation must exist for -/// `TypedValue`. -/// -pub type ValueRc = Arc; - /// Represents one entid in the entid space. /// /// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite diff --git a/edn/src/lib.rs b/edn/src/lib.rs index f8423a37..0527c05a 100644 --- a/edn/src/lib.rs +++ b/edn/src/lib.rs @@ -30,6 +30,12 @@ pub mod types; pub mod pretty_print; pub mod utils; pub mod matcher; +pub mod value_rc; +pub use value_rc::{ + Cloned, + FromRc, + ValueRc, +}; pub mod parse { include!(concat!(env!("OUT_DIR"), "/edn.rs")); diff --git a/edn/src/value_rc.rs b/edn/src/value_rc.rs new file mode 100644 index 00000000..88a5ba7c --- /dev/null +++ b/edn/src/value_rc.rs @@ -0,0 +1,107 @@ +// Copyright 2018 Mozilla +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use +// this file except in compliance with the License. You may obtain a copy of the +// License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +use ::std::rc::{ + Rc, +}; + +use ::std::sync::{ + Arc, +}; + +pub trait FromRc { + fn from_rc(val: Rc) -> Self; + fn from_arc(val: Arc) -> Self; +} + +impl FromRc for Rc where T: Sized + Clone { + fn from_rc(val: Rc) -> Self { + val.clone() + } + + fn from_arc(val: Arc) -> Self { + match ::std::sync::Arc::::try_unwrap(val) { + Ok(v) => Self::new(v), + Err(r) => Self::new(r.cloned()), + } + } +} + +impl FromRc for Arc where T: Sized + Clone { + fn from_rc(val: Rc) -> Self { + match ::std::rc::Rc::::try_unwrap(val) { + Ok(v) => Self::new(v), + Err(r) => Self::new(r.cloned()), + } + } + + fn from_arc(val: Arc) -> Self { + val.clone() + } +} + +impl FromRc for Box where T: Sized + Clone { + fn from_rc(val: Rc) -> Self { + match ::std::rc::Rc::::try_unwrap(val) { + Ok(v) => Self::new(v), + Err(r) => Self::new(r.cloned()), + } + } + + fn from_arc(val: Arc) -> Self { + match ::std::sync::Arc::::try_unwrap(val) { + Ok(v) => Self::new(v), + Err(r) => Self::new(r.cloned()), + } + } +} + +// We do this a lot for errors. +pub trait Cloned { + fn cloned(&self) -> T; + fn to_value_rc(&self) -> ValueRc; +} + +impl Cloned for Rc where T: Sized + Clone { + fn cloned(&self) -> T { + (*self.as_ref()).clone() + } + + fn to_value_rc(&self) -> ValueRc { + ValueRc::from_rc(self.clone()) + } +} + +impl Cloned for Arc where T: Sized + Clone { + fn cloned(&self) -> T { + (*self.as_ref()).clone() + } + + fn to_value_rc(&self) -> ValueRc { + ValueRc::from_arc(self.clone()) + } +} + +impl Cloned for Box where T: Sized + Clone { + fn cloned(&self) -> T { + self.as_ref().clone() + } + + fn to_value_rc(&self) -> ValueRc { + ValueRc::new(self.cloned()) + } +} + +/// +/// This type alias exists to allow us to use different boxing mechanisms for values. +/// This type must implement `FromRc` and `Cloned`, and a `From` implementation must exist for +/// `TypedValue`. +/// +pub type ValueRc = Arc;