Part 1: Expand Binding::val() into Binding::{into_*,as_*}.
This is simply for completeness: we should provide fundamental conversion patterns even when they are mostly unused in our code base.
This commit is contained in:
parent
99deb87b9f
commit
d49f702512
6 changed files with 107 additions and 12 deletions
|
@ -8,6 +8,10 @@
|
||||||
// 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::{
|
use ::std::ffi::{
|
||||||
CString,
|
CString,
|
||||||
};
|
};
|
||||||
|
@ -282,12 +286,47 @@ impl From<Vec<Binding>> for Binding {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Binding {
|
impl Binding {
|
||||||
pub fn val(self) -> Option<TypedValue> {
|
pub fn into_scalar(self) -> Option<TypedValue> {
|
||||||
match self {
|
match self {
|
||||||
Binding::Scalar(v) => Some(v),
|
Binding::Scalar(v) => Some(v),
|
||||||
_ => None,
|
_ => 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
|
/// A pull expression expands a binding into a structure. The returned structure
|
||||||
|
@ -379,15 +418,15 @@ impl TypedValue {
|
||||||
/// Construct a new `TypedValue::Keyword` instance by cloning the provided
|
/// Construct a new `TypedValue::Keyword` instance by cloning the provided
|
||||||
/// values and wrapping them in a new `ValueRc`. This is expensive, so this might
|
/// values and wrapping them in a new `ValueRc`. This is expensive, so this might
|
||||||
/// be best limited to tests.
|
/// be best limited to tests.
|
||||||
pub fn typed_ns_keyword(ns: &str, name: &str) -> TypedValue {
|
pub fn typed_ns_keyword<S: AsRef<str>, T: AsRef<str>>(ns: S, name: T) -> TypedValue {
|
||||||
Keyword::namespaced(ns, name).into()
|
Keyword::namespaced(ns.as_ref(), name.as_ref()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new `TypedValue::String` instance by cloning the provided
|
/// Construct a new `TypedValue::String` instance by cloning the provided
|
||||||
/// value and wrapping it in a new `ValueRc`. This is expensive, so this might
|
/// value and wrapping it in a new `ValueRc`. This is expensive, so this might
|
||||||
/// be best limited to tests.
|
/// be best limited to tests.
|
||||||
pub fn typed_string(s: &str) -> TypedValue {
|
pub fn typed_string<S: AsRef<str>>(s: S) -> TypedValue {
|
||||||
s.into()
|
s.as_ref().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_instant() -> TypedValue {
|
pub fn current_instant() -> TypedValue {
|
||||||
|
@ -736,6 +775,62 @@ impl Binding {
|
||||||
_ => None,
|
_ => 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]
|
#[test]
|
||||||
|
|
|
@ -234,7 +234,7 @@ pub fn lookup_value<'sqlite, 'schema, 'cache, E, A>
|
||||||
fetch_values(sqlite, known, entid, attrid, true)
|
fetch_values(sqlite, known, entid, attrid, true)
|
||||||
.into_scalar_result()
|
.into_scalar_result()
|
||||||
// Safe to unwrap: we never retrieve structure.
|
// Safe to unwrap: we never retrieve structure.
|
||||||
.map(|r| r.map(|v| v.val().unwrap()))
|
.map(|r| r.map(|v| v.into_scalar().unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ pub fn lookup_values<'sqlite, E, A>
|
||||||
fetch_values(sqlite, known, entid, attrid, false)
|
fetch_values(sqlite, known, entid, attrid, false)
|
||||||
.into_coll_result()
|
.into_coll_result()
|
||||||
// Safe to unwrap: we never retrieve structure.
|
// Safe to unwrap: we never retrieve structure.
|
||||||
.map(|v| v.into_iter().map(|x| x.val().unwrap()).collect())
|
.map(|v| v.into_iter().map(|x| x.into_scalar().unwrap()).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -609,7 +609,7 @@ mod tests {
|
||||||
let mut builder = in_progress.builder().describe_tempid(&name);
|
let mut builder = in_progress.builder().describe_tempid(&name);
|
||||||
builder.add(kw!(:todo/uuid), TypedValue::Uuid(uuid)).expect("Expected added uuid");
|
builder.add(kw!(:todo/uuid), TypedValue::Uuid(uuid)).expect("Expected added uuid");
|
||||||
changeset.insert(uuid_entid.clone());
|
changeset.insert(uuid_entid.clone());
|
||||||
builder.add(kw!(:todo/name), TypedValue::typed_string(&name)).expect("Expected added name");
|
builder.add(kw!(:todo/name), TypedValue::typed_string(name)).expect("Expected added name");
|
||||||
changeset.insert(name_entid.clone());
|
changeset.insert(name_entid.clone());
|
||||||
if i % 2 == 0 {
|
if i % 2 == 0 {
|
||||||
builder.add(kw!(:todo/completion_date), TypedValue::current_instant()).expect("Expected added date");
|
builder.add(kw!(:todo/completion_date), TypedValue::current_instant()).expect("Expected added date");
|
||||||
|
@ -678,7 +678,7 @@ mod tests {
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
let name = format!("label{}", i);
|
let name = format!("label{}", i);
|
||||||
let mut builder = in_progress.builder().describe_tempid(&name);
|
let mut builder = in_progress.builder().describe_tempid(&name);
|
||||||
builder.add(kw!(:label/name), TypedValue::typed_string(&name)).expect("Expected added name");
|
builder.add(kw!(:label/name), TypedValue::typed_string(name)).expect("Expected added name");
|
||||||
builder.add(kw!(:label/color), TypedValue::typed_string("blue")).expect("Expected added color");
|
builder.add(kw!(:label/color), TypedValue::typed_string("blue")).expect("Expected added color");
|
||||||
let (ip, _) = builder.transact();
|
let (ip, _) = builder.transact();
|
||||||
in_progress = ip;
|
in_progress = ip;
|
||||||
|
|
|
@ -227,7 +227,7 @@ pub struct Definition {
|
||||||
/// for row in results.into_iter() {
|
/// for row in results.into_iter() {
|
||||||
/// let mut r = row.into_iter();
|
/// let mut r = row.into_iter();
|
||||||
/// let e = r.next().and_then(|e| e.into_known_entid()).expect("entity");
|
/// let e = r.next().and_then(|e| e.into_known_entid()).expect("entity");
|
||||||
/// let obsolete = r.next().expect("value").val().expect("typed value");
|
/// let obsolete = r.next().expect("value").into_scalar().expect("typed value");
|
||||||
/// builder.retract(e, link_title, obsolete)?;
|
/// builder.retract(e, link_title, obsolete)?;
|
||||||
/// }
|
/// }
|
||||||
/// ip.transact_builder(builder)?;
|
/// ip.transact_builder(builder)?;
|
||||||
|
|
|
@ -86,7 +86,7 @@ fn test_simple_pull() {
|
||||||
.expect("hoods")
|
.expect("hoods")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|b| {
|
.map(|b| {
|
||||||
b.val().and_then(|tv| tv.into_entid()).expect("scalar")
|
b.into_scalar().and_then(|tv| tv.into_entid()).expect("scalar")
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ fn av(row: Vec<Binding>) -> (KnownEntid, TypedValue) {
|
||||||
let mut row = row.into_iter();
|
let mut row = row.into_iter();
|
||||||
match (row.next(), row.next()) {
|
match (row.next(), row.next()) {
|
||||||
(Some(Binding::Scalar(TypedValue::Ref(a))), Some(v)) => {
|
(Some(Binding::Scalar(TypedValue::Ref(a))), Some(v)) => {
|
||||||
(KnownEntid(a), v.val().unwrap())
|
(KnownEntid(a), v.into_scalar().unwrap())
|
||||||
},
|
},
|
||||||
_ => panic!("Incorrect query shape for 'av' helper."),
|
_ => panic!("Incorrect query shape for 'av' helper."),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue