use crate::graph::GraphStorage;
use crate::traversal::step::map_steps::temporal::{
ZoneArg, computed, describe, incoming_temporal, input_error, replaced, temporal_error,
};
use crate::value::temporal::Temporal;
use crate::*;
#[derive(Clone)]
struct StepAtZone {
zone: ZoneArg,
}
impl fmt::Display for StepAtZone {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "at_zone({})", self.zone.literal())
}
}
fn step<'g, S: GraphStorage + 'g>(zone: &str) -> GraphStep<'g, S> {
GraphStep::Map(
"at_zone",
Box::new(StepAtZone {
zone: ZoneArg::parse(zone),
}),
)
}
impl<'g, S: GraphStorage + 'g> GraphTraversalSource<'g, S> {
pub fn at_zone(self, zone: &str) -> Self {
self.push_step(step(zone))
}
}
impl __ {
pub fn at_zone<'g, S: GraphStorage + 'g>(zone: &str) -> AnonymousTraversal<'g, S> {
AnonymousTraversal::new().at_zone(zone)
}
}
impl<'g, S: GraphStorage + 'g> AnonymousTraversal<'g, S> {
pub fn at_zone(self, zone: &str) -> Self {
self.push_step(step(zone))
}
}
impl<'g, S: GraphStorage + 'g> GraphStepMap<'g, S> for StepAtZone {
fn process(
&self,
context: &mut TraverserContext<'_, S>,
source: Traverser<S>,
) -> TraverserResult<Traverser<S>> {
const EXPECTED: &str = "a datetime or a localdatetime";
let value = incoming_temporal(context, &source.value, "at_zone", EXPECTED)?;
let zone = self.zone.get("at_zone")?;
let result = match value {
Temporal::DateTime(v) => zone.at(v),
Temporal::LocalDateTime(v) => zone.resolve(v),
other => {
return Err(input_error(
"at_zone",
"incoming value",
EXPECTED,
describe(&ElementProperty::Temporal(other)),
));
}
}
.map_err(|error| temporal_error("at_zone", error))?;
Ok(replaced(source, computed(Temporal::DateTime(result))))
}
fn may_filter(&self) -> bool {
true
}
fn plan_check(&self) -> TraverserResult<()> {
self.zone.check("at_zone")
}
fn clone_box(&self) -> Box<dyn GraphStepMap<'g, S> + 'g> {
Box::new(self.clone())
}
}