Skip to content

Commit

Permalink
More FFI: Finish Calendar, add Instant (#198)
Browse files Browse the repository at this point in the history
Most of what is left is timezone stuff, I think
  • Loading branch information
Manishearth authored Feb 20, 2025
1 parent f047da7 commit 28f24a9
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 225 deletions.
215 changes: 0 additions & 215 deletions temporal_capi/bindings/cpp/diplomat_runtime.hpp

This file was deleted.

Empty file.
130 changes: 129 additions & 1 deletion temporal_capi/src/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
#[diplomat::abi_rename = "temporal_rs_{0}"]
#[diplomat::attr(auto, namespace = "temporal_rs")]
pub mod ffi {
use crate::duration::ffi::Duration;
use crate::error::ffi::TemporalError;
use crate::iso::ffi::IsoDate;
use crate::options::ffi::{ArithmeticOverflow, TemporalUnit};
use crate::plain_date::ffi::{PartialDate, PlainDate};
use crate::plain_month_day::ffi::PlainMonthDay;
use crate::plain_year_month::ffi::PlainYearMonth;
use diplomat_runtime::DiplomatStr;
use std::fmt::Write;

#[diplomat::enum_convert(icu_calendar::any_calendar::AnyCalendarKind, needs_wildcard)]
pub enum AnyCalendarKind {
Expand Down Expand Up @@ -56,6 +63,127 @@ pub mod ffi {
self.0.identifier()
}

// TODO the rest of calendar (needs all the date/time types)
pub fn date_from_partial(
&self,
partial: PartialDate,
overflow: ArithmeticOverflow,
) -> Result<Box<PlainDate>, TemporalError> {
self.0
.date_from_partial(&partial.try_into()?, overflow.into())
.map(|c| Box::new(PlainDate(c)))
.map_err(Into::into)
}

pub fn month_day_from_partial(
&self,
partial: PartialDate,
overflow: ArithmeticOverflow,
) -> Result<Box<PlainMonthDay>, TemporalError> {
self.0
.month_day_from_partial(&partial.try_into()?, overflow.into())
.map(|c| Box::new(PlainMonthDay(c)))
.map_err(Into::into)
}
pub fn year_month_from_partial(
&self,
partial: PartialDate,
overflow: ArithmeticOverflow,
) -> Result<Box<PlainYearMonth>, TemporalError> {
self.0
.year_month_from_partial(&partial.try_into()?, overflow.into())
.map(|c| Box::new(PlainYearMonth(c)))
.map_err(Into::into)
}
pub fn date_add(
&self,
date: IsoDate,
duration: &Duration,
overflow: ArithmeticOverflow,
) -> Result<Box<PlainDate>, TemporalError> {
self.0
.date_add(&date.into(), &duration.0, overflow.into())
.map(|c| Box::new(PlainDate(c)))
.map_err(Into::into)
}
pub fn date_until(
&self,
one: IsoDate,
two: IsoDate,
largest_unit: TemporalUnit,
) -> Result<Box<Duration>, TemporalError> {
self.0
.date_until(&one.into(), &two.into(), largest_unit.into())
.map(|c| Box::new(Duration(c)))
.map_err(Into::into)
}

// Writes an empty string for no era
pub fn era(&self, date: IsoDate, write: &mut DiplomatWrite) -> Result<(), TemporalError> {
let era = self
.0
.era(&date.into())
.map_err(Into::<TemporalError>::into)?;
if let Some(era) = era {
// throw away the error, this should always succeed
let _ = write.write_str(&era);
}
Ok(())
}

pub fn era_year(&self, date: IsoDate) -> Result<Option<i32>, TemporalError> {
self.0.era_year(&date.into()).map_err(Into::into)
}

pub fn year(&self, date: IsoDate) -> Result<i32, TemporalError> {
self.0.year(&date.into()).map_err(Into::into)
}
pub fn month(&self, date: IsoDate) -> Result<u8, TemporalError> {
self.0.month(&date.into()).map_err(Into::into)
}
pub fn month_code(
&self,
date: IsoDate,
write: &mut DiplomatWrite,
) -> Result<(), TemporalError> {
let code = self
.0
.month_code(&date.into())
.map_err(Into::<TemporalError>::into)?;
// throw away the error, this should always succeed
let _ = write.write_str(&code);
Ok(())
}
pub fn day(&self, date: IsoDate) -> Result<u8, TemporalError> {
self.0.day(&date.into()).map_err(Into::into)
}
pub fn day_of_week(&self, date: IsoDate) -> Result<u16, TemporalError> {
self.0.day_of_week(&date.into()).map_err(Into::into)
}
pub fn day_of_year(&self, date: IsoDate) -> Result<u16, TemporalError> {
self.0.day_of_year(&date.into()).map_err(Into::into)
}
pub fn week_of_year(&self, date: IsoDate) -> Result<Option<u16>, TemporalError> {
self.0.week_of_year(&date.into()).map_err(Into::into)
}
pub fn year_of_week(&self, date: IsoDate) -> Result<Option<i32>, TemporalError> {
self.0.year_of_week(&date.into()).map_err(Into::into)
}
pub fn days_in_week(&self, date: IsoDate) -> Result<u16, TemporalError> {
self.0.days_in_week(&date.into()).map_err(Into::into)
}
pub fn days_in_month(&self, date: IsoDate) -> Result<u16, TemporalError> {
self.0.days_in_month(&date.into()).map_err(Into::into)
}
pub fn days_in_year(&self, date: IsoDate) -> Result<u16, TemporalError> {
self.0.days_in_year(&date.into()).map_err(Into::into)
}
pub fn months_in_year(&self, date: IsoDate) -> Result<u16, TemporalError> {
self.0.months_in_year(&date.into()).map_err(Into::into)
}
pub fn in_leap_year(&self, date: IsoDate) -> Result<bool, TemporalError> {
self.0.in_leap_year(&date.into()).map_err(Into::into)
}

// TODO .fields() (need to pick a convenient way to return vectors or iterators, depending on how the API gets used)
}
}
Loading

0 comments on commit 28f24a9

Please sign in to comment.