use crate::inner::models; use std::convert::TryFrom; use upend_base::addressing::{Address, Addressable}; use upend_base::entry::{Entry, EntryValue, ImmutableEntry}; use upend_base::error::UpEndError; impl TryFrom<&models::Entry> for Entry { type Error = UpEndError; fn try_from(e: &models::Entry) -> Result { if let Some(value_str) = &e.value_str { Ok(Entry { entity: Address::decode(&e.entity)?, attribute: e.attribute.parse()?, value: value_str.parse().unwrap(), provenance: e.provenance.clone(), timestamp: e.timestamp, }) } else if let Some(value_num) = e.value_num { Ok(Entry { entity: Address::decode(&e.entity)?, attribute: e.attribute.parse()?, value: EntryValue::Number(value_num), provenance: e.provenance.clone(), timestamp: e.timestamp, }) } else { Ok(Entry { entity: Address::decode(&e.entity)?, attribute: e.attribute.parse()?, value: EntryValue::Number(f64::NAN), provenance: e.provenance.clone(), timestamp: e.timestamp, }) } } } impl TryFrom<&Entry> for models::Entry { type Error = anyhow::Error; fn try_from(e: &Entry) -> Result { let base_entry = models::Entry { identity: e.address()?.encode()?, entity_searchable: match &e.entity { Address::Attribute(attr) => Some(attr.to_string()), Address::Url(url) => Some(url.to_string()), _ => None, }, entity: e.entity.encode()?, attribute: e.attribute.to_string(), value_str: None, value_num: None, immutable: false, provenance: e.provenance.clone(), timestamp: e.timestamp, }; match e.value { EntryValue::Number(n) => Ok(models::Entry { value_str: None, value_num: Some(n), ..base_entry }), _ => Ok(models::Entry { value_str: Some(e.value.to_string()?), value_num: None, ..base_entry }), } } } impl TryFrom<&ImmutableEntry> for models::Entry { type Error = anyhow::Error; fn try_from(e: &ImmutableEntry) -> Result { Ok(models::Entry { immutable: true, ..models::Entry::try_from(&e.0)? }) } }