use crate::graph::GraphStorage;
use crate::traversal::step::map_steps::step_as_date::parse_error;
use crate::traversal::step::map_steps::temporal::{computed, describe, held_value, replaced};
use crate::value::temporal::{Duration, Temporal};
use crate::*;
#[derive(Clone, Default)]
struct StepAsDuration;
impl fmt::Display for StepAsDuration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("as_duration()")
}
}
fn step<'g, S: GraphStorage + 'g>() -> GraphStep<'g, S> {
GraphStep::Map("as_duration", Box::new(StepAsDuration))
}
impl<'g, S: GraphStorage + 'g> GraphTraversalSource<'g, S> {
pub fn as_duration(self) -> Self {
self.push_step(step())
}
}
impl __ {
pub fn as_duration<'g, S: GraphStorage + 'g>() -> AnonymousTraversal<'g, S> {
AnonymousTraversal::new().as_duration()
}
}
impl<'g, S: GraphStorage + 'g> AnonymousTraversal<'g, S> {
pub fn as_duration(self) -> Self {
self.push_step(step())
}
}
fn convert(value: &ElementProperty) -> Result<Duration, String> {
let parse = |text: &str| {
text.parse::<Duration>().map_err(|err| match err {
crate::value::temporal::TemporalError::Parse { reason, .. } => reason.to_string(),
other => other.to_string(),
})
};
match value {
ElementProperty::Temporal(Temporal::Duration(duration)) => Ok(*duration),
ElementProperty::String(text) => parse(text),
ElementProperty::Compressed(text) => text.with_text(parse),
ElementProperty::Null => Err("null is not a duration".to_string()),
other => Err(format!(
"a {} is not a duration",
crate::graph::schema::value_type_name(other)
)),
}
}
impl<'g, S: GraphStorage + 'g> GraphStepMap<'g, S> for StepAsDuration {
fn process(
&self,
context: &mut TraverserContext<'_, S>,
source: Traverser<S>,
) -> TraverserResult<Traverser<S>> {
let converted = match held_value(context, &source.value)? {
Ok(held) => convert(held.as_ref()).map_err(|reason| {
parse_error("as_duration", "duration", describe(&held), reason)
})?,
Err(kind) => {
return Err(parse_error(
"as_duration",
"duration",
format!("a {kind}"),
format!("a {kind} is not a duration"),
));
}
};
Ok(replaced(source, computed(Temporal::Duration(converted))))
}
fn may_filter(&self) -> bool {
true
}
fn clone_box(&self) -> Box<dyn GraphStepMap<'g, S> + 'g> {
Box::new(self.clone())
}
}