Experiments in applying Entity-Component-System patterns to durable data storage APIs.
at main 51 lines 1.6 kB view raw
1use tracing::warn; 2 3use crate::{component, Component}; 4 5#[derive(Debug)] 6pub struct DynComponent<'a>( 7 pub(crate) &'a str, 8 pub(crate) rusqlite::types::ToSqlOutput<'a>, 9); 10 11impl<'a> DynComponent<'a> { 12 pub fn name(&'a self) -> &'a str { 13 self.0 14 } 15 16 pub fn into_typed<C: Component>(self) -> Result<C, component::StorageError> { 17 C::from_rusqlite(&self.1) 18 } 19 20 pub fn as_typed<C: Component>(&self) -> Result<C, component::StorageError> { 21 C::from_rusqlite(&self.1) 22 } 23 24 pub fn from_typed<C: Component + 'a>(c: &'a C) -> Result<Self, component::StorageError> { 25 Ok(Self(C::component_name(), C::to_rusqlite(c)?)) 26 } 27 28 pub fn as_json(&self) -> Option<serde_json::value::Value> { 29 use rusqlite::types::{ToSqlOutput, Value, ValueRef}; 30 31 match self.1 { 32 ToSqlOutput::Borrowed(ValueRef::Text(s)) => serde_json::from_slice(s).ok(), 33 ToSqlOutput::Owned(Value::Text(ref s)) => serde_json::from_slice(s.as_bytes()).ok(), 34 ToSqlOutput::Owned(Value::Null) | ToSqlOutput::Borrowed(ValueRef::Null) => { 35 Some(serde_json::Value::Null) 36 } 37 ToSqlOutput::Owned(ref o) => { 38 warn!(r#type = ?o.data_type(), "DynComponent::as_json unsupported"); 39 None 40 } 41 ToSqlOutput::Borrowed(ref b) => { 42 warn!(r#type = ?b.data_type(), "DynComponent::as_json unsupported"); 43 None 44 } 45 ref x => { 46 warn!(value = ?x, "DynComponent::as_json unsupported"); 47 None 48 } 49 } 50 } 51}