use mf2_runtime::{
Date, DateTime, DateTimeOptions, DateTimeRequest, Dir, FnContext, FormatError, Sink,
SubPartSink, Time, ZoneOption,
};
use crate::zone::wall_ms;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[non_exhaustive]
pub struct Plan<'p> {
pub date: Date,
pub time: Time,
pub offset: Option<i32>,
pub zone: ZoneOption<'p>,
pub options: &'p DateTimeOptions<'p>,
}
impl<'p> Plan<'p> {
pub fn new(cx: &FnContext<'p>, value: &'p DateTime<'p>) -> Plan<'p> {
let zone = match (value.zone, value.options.time_zone) {
(Some(z), _) => ZoneOption::Named(z),
(None, Some(z @ (ZoneOption::Utc | ZoneOption::Offset(_) | ZoneOption::Named(_)))) => z,
(None, _) => cx.time_zone().as_option(),
};
Plan {
date: value.date,
time: value.time,
offset: value.offset,
zone,
options: &value.options,
}
}
pub fn wall_ms(&self) -> i64 {
wall_ms(&DateTime::floating(self.date, self.time))
}
pub fn epoch_ms(&self) -> Option<i64> {
self.offset.map(|o| self.wall_ms() - i64::from(o) * 1000)
}
pub fn request(&self) -> DateTimeRequest<'p> {
match self.epoch_ms() {
Some(epoch_ms) => DateTimeRequest::new(epoch_ms, self.zone, self.options),
None => DateTimeRequest::new(self.wall_ms(), ZoneOption::Utc, self.options),
}
}
}
pub trait Backend: Sync {
fn supports(&self, cx: &FnContext<'_>, plan: &Plan<'_>) -> Result<(), FormatError> {
let _ = (cx, plan);
Ok(())
}
fn format(&self, cx: &FnContext<'_>, plan: &Plan<'_>, out: &mut dyn Sink);
fn format_parts(&self, cx: &FnContext<'_>, plan: &Plan<'_>, out: &mut dyn SubPartSink) {
let _ = (cx, plan, out);
}
fn dir(&self, cx: &FnContext<'_>, plan: &Plan<'_>) -> Dir {
let _ = (cx, plan);
Dir::Ltr
}
}