diff --git a/src/builtins/compiled/zoneddatetime.rs b/src/builtins/compiled/zoneddatetime.rs index fb3177c6e..41c8edc63 100644 --- a/src/builtins/compiled/zoneddatetime.rs +++ b/src/builtins/compiled/zoneddatetime.rs @@ -1,4 +1,5 @@ use crate::builtins::TZ_PROVIDER; +use crate::partial::PartialZonedDateTime; use crate::provider::TransitionDirection; use crate::ZonedDateTime; use crate::{ @@ -222,6 +223,39 @@ impl ZonedDateTime { /// The following [`ZonedDateTime`] methods are feature gated behind the /// `compiled_data` feature flag. impl ZonedDateTime { + #[inline] + pub fn from_partial( + partial: PartialZonedDateTime, + overflow: Option, + disambiguation: Option, + offset_option: Option, + ) -> TemporalResult { + Self::from_partial_with_provider( + partial, + overflow, + disambiguation, + offset_option, + &*crate::builtins::TZ_PROVIDER, + ) + } + + #[inline] + pub fn with( + &self, + partial: PartialZonedDateTime, + disambiguation: Option, + offset_option: Option, + overflow: Option, + ) -> TemporalResult { + self.with_with_provider( + partial, + disambiguation, + offset_option, + overflow, + &*TZ_PROVIDER, + ) + } + /// Creates a new `ZonedDateTime` from the current `ZonedDateTime` with the provided `PlainTime`. /// /// combined with the provided `TimeZone`. diff --git a/src/builtins/core/timezone.rs b/src/builtins/core/timezone.rs index 292d581d9..edfaaf99f 100644 --- a/src/builtins/core/timezone.rs +++ b/src/builtins/core/timezone.rs @@ -128,6 +128,18 @@ impl TimeZone { TimeZone::UtcOffset(offset) => offset.to_string(), } } + + /// but just a getter + pub fn is_valid_with_provider(&self, provider: &impl TimeZoneProvider) -> bool { + match self { + Self::IanaIdentifier(s) => provider.check_identifier(s), + Self::UtcOffset(..) => true, + } + } + #[cfg(feature = "compiled_data")] + pub fn is_valid(&self) -> bool { + self.is_valid_with_provider(&*crate::builtins::TZ_PROVIDER) + } } impl Default for TimeZone { diff --git a/src/builtins/core/zoneddatetime.rs b/src/builtins/core/zoneddatetime.rs index 5f388e811..811f033e5 100644 --- a/src/builtins/core/zoneddatetime.rs +++ b/src/builtins/core/zoneddatetime.rs @@ -521,7 +521,7 @@ impl ZonedDateTime { self.instant } - pub fn with( + pub fn with_with_provider( &self, partial: PartialZonedDateTime, disambiguation: Option, @@ -1602,7 +1602,7 @@ mod tests { let overflow = ArithmeticOverflow::Reject; - let result_1 = zdt.with( + let result_1 = zdt.with_with_provider( PartialZonedDateTime { date: PartialDate { month: Some(29), @@ -1618,7 +1618,7 @@ mod tests { provider, ); - let result_2 = zdt.with( + let result_2 = zdt.with_with_provider( PartialZonedDateTime { date: PartialDate { day: Some(31), @@ -1634,7 +1634,7 @@ mod tests { provider, ); - let result_3 = zdt.with( + let result_3 = zdt.with_with_provider( PartialZonedDateTime { date: PartialDate::default(), time: PartialTime { @@ -1650,7 +1650,7 @@ mod tests { provider, ); - let result_4 = zdt.with( + let result_4 = zdt.with_with_provider( PartialZonedDateTime { date: PartialDate::default(), time: PartialTime { diff --git a/temporal_capi/bindings/c/PartialZonedDateTime.d.h b/temporal_capi/bindings/c/PartialZonedDateTime.d.h new file mode 100644 index 000000000..8261c8797 --- /dev/null +++ b/temporal_capi/bindings/c/PartialZonedDateTime.d.h @@ -0,0 +1,28 @@ +#ifndef PartialZonedDateTime_D_H +#define PartialZonedDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "PartialDate.d.h" +#include "PartialTime.d.h" +#include "TimeZone.d.h" + + + + +typedef struct PartialZonedDateTime { + PartialDate date; + PartialTime time; + OptionStringView offset; + const TimeZone* timezone; +} PartialZonedDateTime; + +typedef struct PartialZonedDateTime_option {union { PartialZonedDateTime ok; }; bool is_ok; } PartialZonedDateTime_option; + + + +#endif // PartialZonedDateTime_D_H diff --git a/temporal_capi/bindings/c/PartialZonedDateTime.h b/temporal_capi/bindings/c/PartialZonedDateTime.h new file mode 100644 index 000000000..2f8305ae3 --- /dev/null +++ b/temporal_capi/bindings/c/PartialZonedDateTime.h @@ -0,0 +1,22 @@ +#ifndef PartialZonedDateTime_H +#define PartialZonedDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "PartialZonedDateTime.d.h" + + + + + + + + + + +#endif // PartialZonedDateTime_H diff --git a/temporal_capi/bindings/c/TimeZone.h b/temporal_capi/bindings/c/TimeZone.h index a2c286a2f..5d707c9be 100644 --- a/temporal_capi/bindings/c/TimeZone.h +++ b/temporal_capi/bindings/c/TimeZone.h @@ -22,6 +22,8 @@ temporal_rs_TimeZone_try_from_identifier_str_result temporal_rs_TimeZone_try_fro typedef struct temporal_rs_TimeZone_try_from_str_result {union {TimeZone* ok; TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_str_result; temporal_rs_TimeZone_try_from_str_result temporal_rs_TimeZone_try_from_str(DiplomatStringView ident); +bool temporal_rs_TimeZone_is_valid(const TimeZone* self); + void temporal_rs_TimeZone_destroy(TimeZone* self); diff --git a/temporal_capi/bindings/c/TransitionDirection.d.h b/temporal_capi/bindings/c/TransitionDirection.d.h new file mode 100644 index 000000000..0976c3ee6 --- /dev/null +++ b/temporal_capi/bindings/c/TransitionDirection.d.h @@ -0,0 +1,23 @@ +#ifndef TransitionDirection_D_H +#define TransitionDirection_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef enum TransitionDirection { + TransitionDirection_Next = 0, + TransitionDirection_Previous = 1, +} TransitionDirection; + +typedef struct TransitionDirection_option {union { TransitionDirection ok; }; bool is_ok; } TransitionDirection_option; + + + +#endif // TransitionDirection_D_H diff --git a/temporal_capi/bindings/c/TransitionDirection.h b/temporal_capi/bindings/c/TransitionDirection.h new file mode 100644 index 000000000..2bc20dd00 --- /dev/null +++ b/temporal_capi/bindings/c/TransitionDirection.h @@ -0,0 +1,22 @@ +#ifndef TransitionDirection_H +#define TransitionDirection_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + +#include "TransitionDirection.d.h" + + + + + + + + + + +#endif // TransitionDirection_H diff --git a/temporal_capi/bindings/c/ZonedDateTime.d.h b/temporal_capi/bindings/c/ZonedDateTime.d.h new file mode 100644 index 000000000..f1380f580 --- /dev/null +++ b/temporal_capi/bindings/c/ZonedDateTime.d.h @@ -0,0 +1,19 @@ +#ifndef ZonedDateTime_D_H +#define ZonedDateTime_D_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + + + + + +typedef struct ZonedDateTime ZonedDateTime; + + + + +#endif // ZonedDateTime_D_H diff --git a/temporal_capi/bindings/c/ZonedDateTime.h b/temporal_capi/bindings/c/ZonedDateTime.h new file mode 100644 index 000000000..7d23ce935 --- /dev/null +++ b/temporal_capi/bindings/c/ZonedDateTime.h @@ -0,0 +1,161 @@ +#ifndef ZonedDateTime_H +#define ZonedDateTime_H + +#include +#include +#include +#include +#include "diplomat_runtime.h" + +#include "AnyCalendarKind.d.h" +#include "ArithmeticOverflow.d.h" +#include "Calendar.d.h" +#include "DifferenceSettings.d.h" +#include "Disambiguation.d.h" +#include "DisplayCalendar.d.h" +#include "DisplayOffset.d.h" +#include "DisplayTimeZone.d.h" +#include "Duration.d.h" +#include "I128Nanoseconds.d.h" +#include "Instant.d.h" +#include "OffsetDisambiguation.d.h" +#include "PartialZonedDateTime.d.h" +#include "PlainDate.d.h" +#include "PlainDateTime.d.h" +#include "PlainTime.d.h" +#include "RoundingOptions.d.h" +#include "TemporalError.d.h" +#include "TimeZone.d.h" +#include "ToStringRoundingOptions.d.h" +#include "TransitionDirection.d.h" + +#include "ZonedDateTime.d.h" + + + + + + +typedef struct temporal_rs_ZonedDateTime_try_new_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_try_new_result; +temporal_rs_ZonedDateTime_try_new_result temporal_rs_ZonedDateTime_try_new(I128Nanoseconds nanosecond, AnyCalendarKind calendar, const TimeZone* time_zone); + +typedef struct temporal_rs_ZonedDateTime_from_partial_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_partial_result; +temporal_rs_ZonedDateTime_from_partial_result temporal_rs_ZonedDateTime_from_partial(PartialZonedDateTime partial, ArithmeticOverflow_option overflow, Disambiguation_option disambiguation, OffsetDisambiguation_option offset_option); + +typedef struct temporal_rs_ZonedDateTime_from_utf8_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf8_result; +temporal_rs_ZonedDateTime_from_utf8_result temporal_rs_ZonedDateTime_from_utf8(DiplomatStringView s, Disambiguation disambiguation, OffsetDisambiguation offset_disambiguation); + +typedef struct temporal_rs_ZonedDateTime_from_utf16_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf16_result; +temporal_rs_ZonedDateTime_from_utf16_result temporal_rs_ZonedDateTime_from_utf16(DiplomatString16View s, Disambiguation disambiguation, OffsetDisambiguation offset_disambiguation); + +int64_t temporal_rs_ZonedDateTime_epoch_milliseconds(const ZonedDateTime* self); + +I128Nanoseconds temporal_rs_ZonedDateTime_epoch_nanoseconds(const ZonedDateTime* self); + +Instant* temporal_rs_ZonedDateTime_to_instant(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_with_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_result; +temporal_rs_ZonedDateTime_with_result temporal_rs_ZonedDateTime_with(const ZonedDateTime* self, PartialZonedDateTime partial, Disambiguation_option disambiguation, OffsetDisambiguation_option offset_option, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_ZonedDateTime_with_timezone_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_timezone_result; +temporal_rs_ZonedDateTime_with_timezone_result temporal_rs_ZonedDateTime_with_timezone(const ZonedDateTime* self, const TimeZone* zone); + +const TimeZone* temporal_rs_ZonedDateTime_timezone(const ZonedDateTime* self); + +int8_t temporal_rs_ZonedDateTime_compare_instant(const ZonedDateTime* self, const ZonedDateTime* other); + +typedef struct temporal_rs_ZonedDateTime_get_time_zone_transition_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_get_time_zone_transition_result; +temporal_rs_ZonedDateTime_get_time_zone_transition_result temporal_rs_ZonedDateTime_get_time_zone_transition(const ZonedDateTime* self, TransitionDirection direction); + +typedef struct temporal_rs_ZonedDateTime_hours_in_day_result {union {uint8_t ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_hours_in_day_result; +temporal_rs_ZonedDateTime_hours_in_day_result temporal_rs_ZonedDateTime_hours_in_day(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_to_plain_datetime_result {union {PlainDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_plain_datetime_result; +temporal_rs_ZonedDateTime_to_plain_datetime_result temporal_rs_ZonedDateTime_to_plain_datetime(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_to_plain_date_result {union {PlainDate* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_plain_date_result; +temporal_rs_ZonedDateTime_to_plain_date_result temporal_rs_ZonedDateTime_to_plain_date(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_to_plain_time_result {union {PlainTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_plain_time_result; +temporal_rs_ZonedDateTime_to_plain_time_result temporal_rs_ZonedDateTime_to_plain_time(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_to_ixdtf_string_result {union { TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_ixdtf_string_result; +temporal_rs_ZonedDateTime_to_ixdtf_string_result temporal_rs_ZonedDateTime_to_ixdtf_string(const ZonedDateTime* self, DisplayOffset display_offset, DisplayTimeZone display_timezone, DisplayCalendar display_calendar, ToStringRoundingOptions options, DiplomatWrite* write); + +typedef struct temporal_rs_ZonedDateTime_with_calendar_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_calendar_result; +temporal_rs_ZonedDateTime_with_calendar_result temporal_rs_ZonedDateTime_with_calendar(const ZonedDateTime* self, AnyCalendarKind calendar); + +typedef struct temporal_rs_ZonedDateTime_with_plain_time_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_plain_time_result; +temporal_rs_ZonedDateTime_with_plain_time_result temporal_rs_ZonedDateTime_with_plain_time(const ZonedDateTime* self, const PlainTime* time); + +typedef struct temporal_rs_ZonedDateTime_add_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_add_result; +temporal_rs_ZonedDateTime_add_result temporal_rs_ZonedDateTime_add(const ZonedDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_ZonedDateTime_subtract_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_subtract_result; +temporal_rs_ZonedDateTime_subtract_result temporal_rs_ZonedDateTime_subtract(const ZonedDateTime* self, const Duration* duration, ArithmeticOverflow_option overflow); + +typedef struct temporal_rs_ZonedDateTime_until_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_until_result; +temporal_rs_ZonedDateTime_until_result temporal_rs_ZonedDateTime_until(const ZonedDateTime* self, const ZonedDateTime* other, DifferenceSettings settings); + +typedef struct temporal_rs_ZonedDateTime_since_result {union {Duration* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_since_result; +temporal_rs_ZonedDateTime_since_result temporal_rs_ZonedDateTime_since(const ZonedDateTime* self, const ZonedDateTime* other, DifferenceSettings settings); + +typedef struct temporal_rs_ZonedDateTime_round_result {union {ZonedDateTime* ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_round_result; +temporal_rs_ZonedDateTime_round_result temporal_rs_ZonedDateTime_round(const ZonedDateTime* self, RoundingOptions options); + +uint8_t temporal_rs_ZonedDateTime_hour(const ZonedDateTime* self); + +uint8_t temporal_rs_ZonedDateTime_minute(const ZonedDateTime* self); + +uint8_t temporal_rs_ZonedDateTime_second(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_millisecond(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_microsecond(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_nanosecond(const ZonedDateTime* self); + +const Calendar* temporal_rs_ZonedDateTime_calendar(const ZonedDateTime* self); + +int32_t temporal_rs_ZonedDateTime_year(const ZonedDateTime* self); + +uint8_t temporal_rs_ZonedDateTime_month(const ZonedDateTime* self); + +void temporal_rs_ZonedDateTime_month_code(const ZonedDateTime* self, DiplomatWrite* write); + +uint8_t temporal_rs_ZonedDateTime_day(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_day_of_week_result {union {uint16_t ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_day_of_week_result; +temporal_rs_ZonedDateTime_day_of_week_result temporal_rs_ZonedDateTime_day_of_week(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_day_of_year(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_week_of_year_result; +temporal_rs_ZonedDateTime_week_of_year_result temporal_rs_ZonedDateTime_week_of_year(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_year_of_week_result; +temporal_rs_ZonedDateTime_year_of_week_result temporal_rs_ZonedDateTime_year_of_week(const ZonedDateTime* self); + +typedef struct temporal_rs_ZonedDateTime_days_in_week_result {union {uint16_t ok; TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_days_in_week_result; +temporal_rs_ZonedDateTime_days_in_week_result temporal_rs_ZonedDateTime_days_in_week(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_days_in_month(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_days_in_year(const ZonedDateTime* self); + +uint16_t temporal_rs_ZonedDateTime_months_in_year(const ZonedDateTime* self); + +bool temporal_rs_ZonedDateTime_in_leap_year(const ZonedDateTime* self); + +void temporal_rs_ZonedDateTime_era(const ZonedDateTime* self, DiplomatWrite* write); + +typedef struct temporal_rs_ZonedDateTime_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_era_year_result; +temporal_rs_ZonedDateTime_era_year_result temporal_rs_ZonedDateTime_era_year(const ZonedDateTime* self); + +void temporal_rs_ZonedDateTime_destroy(ZonedDateTime* self); + + + + + +#endif // ZonedDateTime_H diff --git a/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.d.hpp new file mode 100644 index 000000000..09a647b78 --- /dev/null +++ b/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.d.hpp @@ -0,0 +1,50 @@ +#ifndef temporal_rs_PartialZonedDateTime_D_HPP +#define temporal_rs_PartialZonedDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../diplomat_runtime.hpp" +#include "PartialDate.d.hpp" +#include "PartialTime.d.hpp" + +namespace temporal_rs { +namespace capi { struct TimeZone; } +class TimeZone; +struct PartialDate; +struct PartialTime; +} + + +namespace temporal_rs { +namespace capi { + struct PartialZonedDateTime { + temporal_rs::capi::PartialDate date; + temporal_rs::capi::PartialTime time; + diplomat::capi::OptionStringView offset; + const temporal_rs::capi::TimeZone* timezone; + }; + + typedef struct PartialZonedDateTime_option {union { PartialZonedDateTime ok; }; bool is_ok; } PartialZonedDateTime_option; +} // namespace capi +} // namespace + + +namespace temporal_rs { +struct PartialZonedDateTime { + temporal_rs::PartialDate date; + temporal_rs::PartialTime time; + std::optional offset; + const temporal_rs::TimeZone* timezone; + + inline temporal_rs::capi::PartialZonedDateTime AsFFI() const; + inline static temporal_rs::PartialZonedDateTime FromFFI(temporal_rs::capi::PartialZonedDateTime c_struct); +}; + +} // namespace +#endif // temporal_rs_PartialZonedDateTime_D_HPP diff --git a/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.hpp b/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.hpp new file mode 100644 index 000000000..b5a025ed6 --- /dev/null +++ b/temporal_capi/bindings/cpp/temporal_rs/PartialZonedDateTime.hpp @@ -0,0 +1,48 @@ +#ifndef temporal_rs_PartialZonedDateTime_HPP +#define temporal_rs_PartialZonedDateTime_HPP + +#include "PartialZonedDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../diplomat_runtime.hpp" +#include "PartialDate.hpp" +#include "PartialTime.hpp" +#include "TimeZone.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + + +inline temporal_rs::capi::PartialZonedDateTime temporal_rs::PartialZonedDateTime::AsFFI() const { + return temporal_rs::capi::PartialZonedDateTime { + /* .date = */ date.AsFFI(), + /* .time = */ time.AsFFI(), + /* .offset = */ offset.has_value() ? (diplomat::capi::OptionStringView{ { {offset.value().data(), offset.value().size()} }, true }) : (diplomat::capi::OptionStringView{ {}, false }), + /* .timezone = */ timezone ? timezone->AsFFI() : nullptr, + }; +} + +inline temporal_rs::PartialZonedDateTime temporal_rs::PartialZonedDateTime::FromFFI(temporal_rs::capi::PartialZonedDateTime c_struct) { + return temporal_rs::PartialZonedDateTime { + /* .date = */ temporal_rs::PartialDate::FromFFI(c_struct.date), + /* .time = */ temporal_rs::PartialTime::FromFFI(c_struct.time), + /* .offset = */ c_struct.offset.is_ok ? std::optional(std::string_view(c_struct.offset.ok.data, c_struct.offset.ok.len)) : std::nullopt, + /* .timezone = */ temporal_rs::TimeZone::FromFFI(c_struct.timezone), + }; +} + + +#endif // temporal_rs_PartialZonedDateTime_HPP diff --git a/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp index 3b1c0009c..e78bacc67 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/TimeZone.d.hpp @@ -32,6 +32,8 @@ class TimeZone { inline static diplomat::result, temporal_rs::TemporalError> try_from_str(std::string_view ident); + inline bool is_valid() const; + inline const temporal_rs::capi::TimeZone* AsFFI() const; inline temporal_rs::capi::TimeZone* AsFFI(); inline static const temporal_rs::TimeZone* FromFFI(const temporal_rs::capi::TimeZone* ptr); diff --git a/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp b/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp index 818f14060..2ebc904b8 100644 --- a/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp +++ b/temporal_capi/bindings/cpp/temporal_rs/TimeZone.hpp @@ -25,6 +25,8 @@ namespace capi { typedef struct temporal_rs_TimeZone_try_from_str_result {union {temporal_rs::capi::TimeZone* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_TimeZone_try_from_str_result; temporal_rs_TimeZone_try_from_str_result temporal_rs_TimeZone_try_from_str(diplomat::capi::DiplomatStringView ident); + bool temporal_rs_TimeZone_is_valid(const temporal_rs::capi::TimeZone* self); + void temporal_rs_TimeZone_destroy(TimeZone* self); } // extern "C" @@ -41,6 +43,11 @@ inline diplomat::result, temporal_rs::Tem return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::TimeZone::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); } +inline bool temporal_rs::TimeZone::is_valid() const { + auto result = temporal_rs::capi::temporal_rs_TimeZone_is_valid(this->AsFFI()); + return result; +} + inline const temporal_rs::capi::TimeZone* temporal_rs::TimeZone::AsFFI() const { return reinterpret_cast(this); } diff --git a/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.d.hpp new file mode 100644 index 000000000..3a474ebd4 --- /dev/null +++ b/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.d.hpp @@ -0,0 +1,48 @@ +#ifndef temporal_rs_TransitionDirection_D_HPP +#define temporal_rs_TransitionDirection_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + enum TransitionDirection { + TransitionDirection_Next = 0, + TransitionDirection_Previous = 1, + }; + + typedef struct TransitionDirection_option {union { TransitionDirection ok; }; bool is_ok; } TransitionDirection_option; +} // namespace capi +} // namespace + +namespace temporal_rs { +class TransitionDirection { +public: + enum Value { + Next = 0, + Previous = 1, + }; + + TransitionDirection() = default; + // Implicit conversions between enum and ::Value + constexpr TransitionDirection(Value v) : value(v) {} + constexpr operator Value() const { return value; } + // Prevent usage as boolean value + explicit operator bool() const = delete; + + inline temporal_rs::capi::TransitionDirection AsFFI() const; + inline static temporal_rs::TransitionDirection FromFFI(temporal_rs::capi::TransitionDirection c_enum); +private: + Value value; +}; + +} // namespace +#endif // temporal_rs_TransitionDirection_D_HPP diff --git a/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.hpp b/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.hpp new file mode 100644 index 000000000..9eb56e1ad --- /dev/null +++ b/temporal_capi/bindings/cpp/temporal_rs/TransitionDirection.hpp @@ -0,0 +1,38 @@ +#ifndef temporal_rs_TransitionDirection_HPP +#define temporal_rs_TransitionDirection_HPP + +#include "TransitionDirection.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../diplomat_runtime.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + } // extern "C" +} // namespace capi +} // namespace + +inline temporal_rs::capi::TransitionDirection temporal_rs::TransitionDirection::AsFFI() const { + return static_cast(value); +} + +inline temporal_rs::TransitionDirection temporal_rs::TransitionDirection::FromFFI(temporal_rs::capi::TransitionDirection c_enum) { + switch (c_enum) { + case temporal_rs::capi::TransitionDirection_Next: + case temporal_rs::capi::TransitionDirection_Previous: + return static_cast(c_enum); + default: + std::abort(); + } +} +#endif // temporal_rs_TransitionDirection_HPP diff --git a/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.d.hpp b/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.d.hpp new file mode 100644 index 000000000..c3c1965bc --- /dev/null +++ b/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.d.hpp @@ -0,0 +1,165 @@ +#ifndef temporal_rs_ZonedDateTime_D_HPP +#define temporal_rs_ZonedDateTime_D_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../diplomat_runtime.hpp" + +namespace temporal_rs { +namespace capi { struct Calendar; } +class Calendar; +namespace capi { struct Duration; } +class Duration; +namespace capi { struct Instant; } +class Instant; +namespace capi { struct PlainDate; } +class PlainDate; +namespace capi { struct PlainDateTime; } +class PlainDateTime; +namespace capi { struct PlainTime; } +class PlainTime; +namespace capi { struct TimeZone; } +class TimeZone; +namespace capi { struct ZonedDateTime; } +class ZonedDateTime; +struct DifferenceSettings; +struct I128Nanoseconds; +struct PartialZonedDateTime; +struct RoundingOptions; +struct TemporalError; +struct ToStringRoundingOptions; +class AnyCalendarKind; +class ArithmeticOverflow; +class Disambiguation; +class DisplayCalendar; +class DisplayOffset; +class DisplayTimeZone; +class OffsetDisambiguation; +class TransitionDirection; +} + + +namespace temporal_rs { +namespace capi { + struct ZonedDateTime; +} // namespace capi +} // namespace + +namespace temporal_rs { +class ZonedDateTime { +public: + + inline static diplomat::result, temporal_rs::TemporalError> try_new(temporal_rs::I128Nanoseconds nanosecond, temporal_rs::AnyCalendarKind calendar, const temporal_rs::TimeZone& time_zone); + + inline static diplomat::result, temporal_rs::TemporalError> from_partial(temporal_rs::PartialZonedDateTime partial, std::optional overflow, std::optional disambiguation, std::optional offset_option); + + inline static diplomat::result, temporal_rs::TemporalError> from_utf8(std::string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation); + + inline static diplomat::result, temporal_rs::TemporalError> from_utf16(std::u16string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation); + + inline int64_t epoch_milliseconds() const; + + inline temporal_rs::I128Nanoseconds epoch_nanoseconds() const; + + inline std::unique_ptr to_instant() const; + + inline diplomat::result, temporal_rs::TemporalError> with(temporal_rs::PartialZonedDateTime partial, std::optional disambiguation, std::optional offset_option, std::optional overflow) const; + + inline diplomat::result, temporal_rs::TemporalError> with_timezone(const temporal_rs::TimeZone& zone) const; + + inline const temporal_rs::TimeZone& timezone() const; + + inline int8_t compare_instant(const temporal_rs::ZonedDateTime& other) const; + + inline diplomat::result, temporal_rs::TemporalError> get_time_zone_transition(temporal_rs::TransitionDirection direction) const; + + inline diplomat::result hours_in_day() const; + + inline diplomat::result, temporal_rs::TemporalError> to_plain_datetime() const; + + inline diplomat::result, temporal_rs::TemporalError> to_plain_date() const; + + inline diplomat::result, temporal_rs::TemporalError> to_plain_time() const; + + inline diplomat::result to_ixdtf_string(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options) const; + + inline diplomat::result, temporal_rs::TemporalError> with_calendar(temporal_rs::AnyCalendarKind calendar) const; + + inline diplomat::result, temporal_rs::TemporalError> with_plain_time(const temporal_rs::PlainTime& time) const; + + inline diplomat::result, temporal_rs::TemporalError> add(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline diplomat::result, temporal_rs::TemporalError> subtract(const temporal_rs::Duration& duration, std::optional overflow) const; + + inline diplomat::result, temporal_rs::TemporalError> until(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const; + + inline diplomat::result, temporal_rs::TemporalError> since(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const; + + inline diplomat::result, temporal_rs::TemporalError> round(temporal_rs::RoundingOptions options) const; + + inline uint8_t hour() const; + + inline uint8_t minute() const; + + inline uint8_t second() const; + + inline uint16_t millisecond() const; + + inline uint16_t microsecond() const; + + inline uint16_t nanosecond() const; + + inline const temporal_rs::Calendar& calendar() const; + + inline int32_t year() const; + + inline uint8_t month() const; + + inline std::string month_code() const; + + inline uint8_t day() const; + + inline diplomat::result day_of_week() const; + + inline uint16_t day_of_year() const; + + inline std::optional week_of_year() const; + + inline std::optional year_of_week() const; + + inline diplomat::result days_in_week() const; + + inline uint16_t days_in_month() const; + + inline uint16_t days_in_year() const; + + inline uint16_t months_in_year() const; + + inline bool in_leap_year() const; + + inline std::string era() const; + + inline std::optional era_year() const; + + inline const temporal_rs::capi::ZonedDateTime* AsFFI() const; + inline temporal_rs::capi::ZonedDateTime* AsFFI(); + inline static const temporal_rs::ZonedDateTime* FromFFI(const temporal_rs::capi::ZonedDateTime* ptr); + inline static temporal_rs::ZonedDateTime* FromFFI(temporal_rs::capi::ZonedDateTime* ptr); + inline static void operator delete(void* ptr); +private: + ZonedDateTime() = delete; + ZonedDateTime(const temporal_rs::ZonedDateTime&) = delete; + ZonedDateTime(temporal_rs::ZonedDateTime&&) noexcept = delete; + ZonedDateTime operator=(const temporal_rs::ZonedDateTime&) = delete; + ZonedDateTime operator=(temporal_rs::ZonedDateTime&&) noexcept = delete; + static void operator delete[](void*, size_t) = delete; +}; + +} // namespace +#endif // temporal_rs_ZonedDateTime_D_HPP diff --git a/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.hpp b/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.hpp new file mode 100644 index 000000000..b4887d6a2 --- /dev/null +++ b/temporal_capi/bindings/cpp/temporal_rs/ZonedDateTime.hpp @@ -0,0 +1,455 @@ +#ifndef temporal_rs_ZonedDateTime_HPP +#define temporal_rs_ZonedDateTime_HPP + +#include "ZonedDateTime.d.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../diplomat_runtime.hpp" +#include "AnyCalendarKind.hpp" +#include "ArithmeticOverflow.hpp" +#include "Calendar.hpp" +#include "DifferenceSettings.hpp" +#include "Disambiguation.hpp" +#include "DisplayCalendar.hpp" +#include "DisplayOffset.hpp" +#include "DisplayTimeZone.hpp" +#include "Duration.hpp" +#include "I128Nanoseconds.hpp" +#include "Instant.hpp" +#include "OffsetDisambiguation.hpp" +#include "PartialZonedDateTime.hpp" +#include "PlainDate.hpp" +#include "PlainDateTime.hpp" +#include "PlainTime.hpp" +#include "RoundingOptions.hpp" +#include "TemporalError.hpp" +#include "TimeZone.hpp" +#include "ToStringRoundingOptions.hpp" +#include "TransitionDirection.hpp" + + +namespace temporal_rs { +namespace capi { + extern "C" { + + typedef struct temporal_rs_ZonedDateTime_try_new_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_try_new_result; + temporal_rs_ZonedDateTime_try_new_result temporal_rs_ZonedDateTime_try_new(temporal_rs::capi::I128Nanoseconds nanosecond, temporal_rs::capi::AnyCalendarKind calendar, const temporal_rs::capi::TimeZone* time_zone); + + typedef struct temporal_rs_ZonedDateTime_from_partial_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_partial_result; + temporal_rs_ZonedDateTime_from_partial_result temporal_rs_ZonedDateTime_from_partial(temporal_rs::capi::PartialZonedDateTime partial, temporal_rs::capi::ArithmeticOverflow_option overflow, temporal_rs::capi::Disambiguation_option disambiguation, temporal_rs::capi::OffsetDisambiguation_option offset_option); + + typedef struct temporal_rs_ZonedDateTime_from_utf8_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf8_result; + temporal_rs_ZonedDateTime_from_utf8_result temporal_rs_ZonedDateTime_from_utf8(diplomat::capi::DiplomatStringView s, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_disambiguation); + + typedef struct temporal_rs_ZonedDateTime_from_utf16_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_from_utf16_result; + temporal_rs_ZonedDateTime_from_utf16_result temporal_rs_ZonedDateTime_from_utf16(diplomat::capi::DiplomatString16View s, temporal_rs::capi::Disambiguation disambiguation, temporal_rs::capi::OffsetDisambiguation offset_disambiguation); + + int64_t temporal_rs_ZonedDateTime_epoch_milliseconds(const temporal_rs::capi::ZonedDateTime* self); + + temporal_rs::capi::I128Nanoseconds temporal_rs_ZonedDateTime_epoch_nanoseconds(const temporal_rs::capi::ZonedDateTime* self); + + temporal_rs::capi::Instant* temporal_rs_ZonedDateTime_to_instant(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_with_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_result; + temporal_rs_ZonedDateTime_with_result temporal_rs_ZonedDateTime_with(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::PartialZonedDateTime partial, temporal_rs::capi::Disambiguation_option disambiguation, temporal_rs::capi::OffsetDisambiguation_option offset_option, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_ZonedDateTime_with_timezone_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_timezone_result; + temporal_rs_ZonedDateTime_with_timezone_result temporal_rs_ZonedDateTime_with_timezone(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::TimeZone* zone); + + const temporal_rs::capi::TimeZone* temporal_rs_ZonedDateTime_timezone(const temporal_rs::capi::ZonedDateTime* self); + + int8_t temporal_rs_ZonedDateTime_compare_instant(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other); + + typedef struct temporal_rs_ZonedDateTime_get_time_zone_transition_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_get_time_zone_transition_result; + temporal_rs_ZonedDateTime_get_time_zone_transition_result temporal_rs_ZonedDateTime_get_time_zone_transition(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::TransitionDirection direction); + + typedef struct temporal_rs_ZonedDateTime_hours_in_day_result {union {uint8_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_hours_in_day_result; + temporal_rs_ZonedDateTime_hours_in_day_result temporal_rs_ZonedDateTime_hours_in_day(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_to_plain_datetime_result {union {temporal_rs::capi::PlainDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_plain_datetime_result; + temporal_rs_ZonedDateTime_to_plain_datetime_result temporal_rs_ZonedDateTime_to_plain_datetime(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_to_plain_date_result {union {temporal_rs::capi::PlainDate* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_plain_date_result; + temporal_rs_ZonedDateTime_to_plain_date_result temporal_rs_ZonedDateTime_to_plain_date(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_to_plain_time_result {union {temporal_rs::capi::PlainTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_plain_time_result; + temporal_rs_ZonedDateTime_to_plain_time_result temporal_rs_ZonedDateTime_to_plain_time(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_to_ixdtf_string_result {union { temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_to_ixdtf_string_result; + temporal_rs_ZonedDateTime_to_ixdtf_string_result temporal_rs_ZonedDateTime_to_ixdtf_string(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::DisplayOffset display_offset, temporal_rs::capi::DisplayTimeZone display_timezone, temporal_rs::capi::DisplayCalendar display_calendar, temporal_rs::capi::ToStringRoundingOptions options, diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_ZonedDateTime_with_calendar_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_calendar_result; + temporal_rs_ZonedDateTime_with_calendar_result temporal_rs_ZonedDateTime_with_calendar(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::AnyCalendarKind calendar); + + typedef struct temporal_rs_ZonedDateTime_with_plain_time_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_with_plain_time_result; + temporal_rs_ZonedDateTime_with_plain_time_result temporal_rs_ZonedDateTime_with_plain_time(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::PlainTime* time); + + typedef struct temporal_rs_ZonedDateTime_add_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_add_result; + temporal_rs_ZonedDateTime_add_result temporal_rs_ZonedDateTime_add(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_ZonedDateTime_subtract_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_subtract_result; + temporal_rs_ZonedDateTime_subtract_result temporal_rs_ZonedDateTime_subtract(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::Duration* duration, temporal_rs::capi::ArithmeticOverflow_option overflow); + + typedef struct temporal_rs_ZonedDateTime_until_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_until_result; + temporal_rs_ZonedDateTime_until_result temporal_rs_ZonedDateTime_until(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_ZonedDateTime_since_result {union {temporal_rs::capi::Duration* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_since_result; + temporal_rs_ZonedDateTime_since_result temporal_rs_ZonedDateTime_since(const temporal_rs::capi::ZonedDateTime* self, const temporal_rs::capi::ZonedDateTime* other, temporal_rs::capi::DifferenceSettings settings); + + typedef struct temporal_rs_ZonedDateTime_round_result {union {temporal_rs::capi::ZonedDateTime* ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_round_result; + temporal_rs_ZonedDateTime_round_result temporal_rs_ZonedDateTime_round(const temporal_rs::capi::ZonedDateTime* self, temporal_rs::capi::RoundingOptions options); + + uint8_t temporal_rs_ZonedDateTime_hour(const temporal_rs::capi::ZonedDateTime* self); + + uint8_t temporal_rs_ZonedDateTime_minute(const temporal_rs::capi::ZonedDateTime* self); + + uint8_t temporal_rs_ZonedDateTime_second(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_millisecond(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_microsecond(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_nanosecond(const temporal_rs::capi::ZonedDateTime* self); + + const temporal_rs::capi::Calendar* temporal_rs_ZonedDateTime_calendar(const temporal_rs::capi::ZonedDateTime* self); + + int32_t temporal_rs_ZonedDateTime_year(const temporal_rs::capi::ZonedDateTime* self); + + uint8_t temporal_rs_ZonedDateTime_month(const temporal_rs::capi::ZonedDateTime* self); + + void temporal_rs_ZonedDateTime_month_code(const temporal_rs::capi::ZonedDateTime* self, diplomat::capi::DiplomatWrite* write); + + uint8_t temporal_rs_ZonedDateTime_day(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_day_of_week_result {union {uint16_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_day_of_week_result; + temporal_rs_ZonedDateTime_day_of_week_result temporal_rs_ZonedDateTime_day_of_week(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_day_of_year(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_week_of_year_result {union {uint8_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_week_of_year_result; + temporal_rs_ZonedDateTime_week_of_year_result temporal_rs_ZonedDateTime_week_of_year(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_year_of_week_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_year_of_week_result; + temporal_rs_ZonedDateTime_year_of_week_result temporal_rs_ZonedDateTime_year_of_week(const temporal_rs::capi::ZonedDateTime* self); + + typedef struct temporal_rs_ZonedDateTime_days_in_week_result {union {uint16_t ok; temporal_rs::capi::TemporalError err;}; bool is_ok;} temporal_rs_ZonedDateTime_days_in_week_result; + temporal_rs_ZonedDateTime_days_in_week_result temporal_rs_ZonedDateTime_days_in_week(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_days_in_month(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_days_in_year(const temporal_rs::capi::ZonedDateTime* self); + + uint16_t temporal_rs_ZonedDateTime_months_in_year(const temporal_rs::capi::ZonedDateTime* self); + + bool temporal_rs_ZonedDateTime_in_leap_year(const temporal_rs::capi::ZonedDateTime* self); + + void temporal_rs_ZonedDateTime_era(const temporal_rs::capi::ZonedDateTime* self, diplomat::capi::DiplomatWrite* write); + + typedef struct temporal_rs_ZonedDateTime_era_year_result {union {int32_t ok; }; bool is_ok;} temporal_rs_ZonedDateTime_era_year_result; + temporal_rs_ZonedDateTime_era_year_result temporal_rs_ZonedDateTime_era_year(const temporal_rs::capi::ZonedDateTime* self); + + void temporal_rs_ZonedDateTime_destroy(ZonedDateTime* self); + + } // extern "C" +} // namespace capi +} // namespace + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::try_new(temporal_rs::I128Nanoseconds nanosecond, temporal_rs::AnyCalendarKind calendar, const temporal_rs::TimeZone& time_zone) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_try_new(nanosecond.AsFFI(), + calendar.AsFFI(), + time_zone.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_partial(temporal_rs::PartialZonedDateTime partial, std::optional overflow, std::optional disambiguation, std::optional offset_option) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_partial(partial.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false }), + disambiguation.has_value() ? (temporal_rs::capi::Disambiguation_option{ { disambiguation.value().AsFFI() }, true }) : (temporal_rs::capi::Disambiguation_option{ {}, false }), + offset_option.has_value() ? (temporal_rs::capi::OffsetDisambiguation_option{ { offset_option.value().AsFFI() }, true }) : (temporal_rs::capi::OffsetDisambiguation_option{ {}, false })); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_utf8(std::string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_utf8({s.data(), s.size()}, + disambiguation.AsFFI(), + offset_disambiguation.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::from_utf16(std::u16string_view s, temporal_rs::Disambiguation disambiguation, temporal_rs::OffsetDisambiguation offset_disambiguation) { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_from_utf16({s.data(), s.size()}, + disambiguation.AsFFI(), + offset_disambiguation.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline int64_t temporal_rs::ZonedDateTime::epoch_milliseconds() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_epoch_milliseconds(this->AsFFI()); + return result; +} + +inline temporal_rs::I128Nanoseconds temporal_rs::ZonedDateTime::epoch_nanoseconds() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_epoch_nanoseconds(this->AsFFI()); + return temporal_rs::I128Nanoseconds::FromFFI(result); +} + +inline std::unique_ptr temporal_rs::ZonedDateTime::to_instant() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_instant(this->AsFFI()); + return std::unique_ptr(temporal_rs::Instant::FromFFI(result)); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with(temporal_rs::PartialZonedDateTime partial, std::optional disambiguation, std::optional offset_option, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with(this->AsFFI(), + partial.AsFFI(), + disambiguation.has_value() ? (temporal_rs::capi::Disambiguation_option{ { disambiguation.value().AsFFI() }, true }) : (temporal_rs::capi::Disambiguation_option{ {}, false }), + offset_option.has_value() ? (temporal_rs::capi::OffsetDisambiguation_option{ { offset_option.value().AsFFI() }, true }) : (temporal_rs::capi::OffsetDisambiguation_option{ {}, false }), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_timezone(const temporal_rs::TimeZone& zone) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_timezone(this->AsFFI(), + zone.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline const temporal_rs::TimeZone& temporal_rs::ZonedDateTime::timezone() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_timezone(this->AsFFI()); + return *temporal_rs::TimeZone::FromFFI(result); +} + +inline int8_t temporal_rs::ZonedDateTime::compare_instant(const temporal_rs::ZonedDateTime& other) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_compare_instant(this->AsFFI(), + other.AsFFI()); + return result; +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::get_time_zone_transition(temporal_rs::TransitionDirection direction) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_get_time_zone_transition(this->AsFFI(), + direction.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result temporal_rs::ZonedDateTime::hours_in_day() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_hours_in_day(this->AsFFI()); + return result.is_ok ? diplomat::result(diplomat::Ok(result.ok)) : diplomat::result(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::to_plain_datetime() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_plain_datetime(this->AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::to_plain_date() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_plain_date(this->AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::PlainDate::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::to_plain_time() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_plain_time(this->AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::PlainTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result temporal_rs::ZonedDateTime::to_ixdtf_string(temporal_rs::DisplayOffset display_offset, temporal_rs::DisplayTimeZone display_timezone, temporal_rs::DisplayCalendar display_calendar, temporal_rs::ToStringRoundingOptions options) const { + std::string output; + diplomat::capi::DiplomatWrite write = diplomat::WriteFromString(output); + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_to_ixdtf_string(this->AsFFI(), + display_offset.AsFFI(), + display_timezone.AsFFI(), + display_calendar.AsFFI(), + options.AsFFI(), + &write); + return result.is_ok ? diplomat::result(diplomat::Ok(std::move(output))) : diplomat::result(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_calendar(temporal_rs::AnyCalendarKind calendar) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_calendar(this->AsFFI(), + calendar.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::with_plain_time(const temporal_rs::PlainTime& time) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_with_plain_time(this->AsFFI(), + time.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::add(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_add(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::subtract(const temporal_rs::Duration& duration, std::optional overflow) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_subtract(this->AsFFI(), + duration.AsFFI(), + overflow.has_value() ? (temporal_rs::capi::ArithmeticOverflow_option{ { overflow.value().AsFFI() }, true }) : (temporal_rs::capi::ArithmeticOverflow_option{ {}, false })); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::until(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_until(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::since(const temporal_rs::ZonedDateTime& other, temporal_rs::DifferenceSettings settings) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_since(this->AsFFI(), + other.AsFFI(), + settings.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::Duration::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline diplomat::result, temporal_rs::TemporalError> temporal_rs::ZonedDateTime::round(temporal_rs::RoundingOptions options) const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_round(this->AsFFI(), + options.AsFFI()); + return result.is_ok ? diplomat::result, temporal_rs::TemporalError>(diplomat::Ok>(std::unique_ptr(temporal_rs::ZonedDateTime::FromFFI(result.ok)))) : diplomat::result, temporal_rs::TemporalError>(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint8_t temporal_rs::ZonedDateTime::hour() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_hour(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::ZonedDateTime::minute() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_minute(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::ZonedDateTime::second() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_second(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::millisecond() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_millisecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::microsecond() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_microsecond(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::nanosecond() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_nanosecond(this->AsFFI()); + return result; +} + +inline const temporal_rs::Calendar& temporal_rs::ZonedDateTime::calendar() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_calendar(this->AsFFI()); + return *temporal_rs::Calendar::FromFFI(result); +} + +inline int32_t temporal_rs::ZonedDateTime::year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_year(this->AsFFI()); + return result; +} + +inline uint8_t temporal_rs::ZonedDateTime::month() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_month(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::ZonedDateTime::month_code() const { + std::string output; + diplomat::capi::DiplomatWrite write = diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_ZonedDateTime_month_code(this->AsFFI(), + &write); + return output; +} + +inline uint8_t temporal_rs::ZonedDateTime::day() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_day(this->AsFFI()); + return result; +} + +inline diplomat::result temporal_rs::ZonedDateTime::day_of_week() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_day_of_week(this->AsFFI()); + return result.is_ok ? diplomat::result(diplomat::Ok(result.ok)) : diplomat::result(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint16_t temporal_rs::ZonedDateTime::day_of_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_day_of_year(this->AsFFI()); + return result; +} + +inline std::optional temporal_rs::ZonedDateTime::week_of_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_week_of_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline std::optional temporal_rs::ZonedDateTime::year_of_week() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_year_of_week(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline diplomat::result temporal_rs::ZonedDateTime::days_in_week() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_days_in_week(this->AsFFI()); + return result.is_ok ? diplomat::result(diplomat::Ok(result.ok)) : diplomat::result(diplomat::Err(temporal_rs::TemporalError::FromFFI(result.err))); +} + +inline uint16_t temporal_rs::ZonedDateTime::days_in_month() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_days_in_month(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::days_in_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_days_in_year(this->AsFFI()); + return result; +} + +inline uint16_t temporal_rs::ZonedDateTime::months_in_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_months_in_year(this->AsFFI()); + return result; +} + +inline bool temporal_rs::ZonedDateTime::in_leap_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_in_leap_year(this->AsFFI()); + return result; +} + +inline std::string temporal_rs::ZonedDateTime::era() const { + std::string output; + diplomat::capi::DiplomatWrite write = diplomat::WriteFromString(output); + temporal_rs::capi::temporal_rs_ZonedDateTime_era(this->AsFFI(), + &write); + return output; +} + +inline std::optional temporal_rs::ZonedDateTime::era_year() const { + auto result = temporal_rs::capi::temporal_rs_ZonedDateTime_era_year(this->AsFFI()); + return result.is_ok ? std::optional(result.ok) : std::nullopt; +} + +inline const temporal_rs::capi::ZonedDateTime* temporal_rs::ZonedDateTime::AsFFI() const { + return reinterpret_cast(this); +} + +inline temporal_rs::capi::ZonedDateTime* temporal_rs::ZonedDateTime::AsFFI() { + return reinterpret_cast(this); +} + +inline const temporal_rs::ZonedDateTime* temporal_rs::ZonedDateTime::FromFFI(const temporal_rs::capi::ZonedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline temporal_rs::ZonedDateTime* temporal_rs::ZonedDateTime::FromFFI(temporal_rs::capi::ZonedDateTime* ptr) { + return reinterpret_cast(ptr); +} + +inline void temporal_rs::ZonedDateTime::operator delete(void* ptr) { + temporal_rs::capi::temporal_rs_ZonedDateTime_destroy(reinterpret_cast(ptr)); +} + + +#endif // temporal_rs_ZonedDateTime_HPP diff --git a/temporal_capi/src/instant.rs b/temporal_capi/src/instant.rs index 3c6e5a51e..ba267efdd 100644 --- a/temporal_capi/src/instant.rs +++ b/temporal_capi/src/instant.rs @@ -30,13 +30,7 @@ pub mod ffi { impl Instant { pub fn try_new(ns: I128Nanoseconds) -> Result, TemporalError> { - let is_neg = ns.high < 0; - let ns_high_abs = ns.high.unsigned_abs() as u128; - // Stick them together - let total = ((ns_high_abs << 64) + ns.low as u128) as i128; - // Reintroduce the sign - let instant = if is_neg { -total } else { total }; - temporal_rs::Instant::try_new(instant) + temporal_rs::Instant::try_new(ns.into()) .map(|c| Box::new(Self(c))) .map_err(Into::into) } @@ -134,14 +128,7 @@ pub mod ffi { pub fn epoch_nanoseconds(&self) -> I128Nanoseconds { let ns = self.0.epoch_nanoseconds().as_i128(); - let is_neg = ns < 0; - let ns = ns.unsigned_abs(); - - let high = (ns >> 64) as i64; - let low = (ns & u64::MAX as u128) as u64; - let high = if is_neg { -high } else { high }; - - I128Nanoseconds { high, low } + ns.into() } #[cfg(feature = "compiled_data")] @@ -162,3 +149,31 @@ pub mod ffi { // TODO non-compiled data timezone APIs } } + +impl From for i128 { + fn from(ns: ffi::I128Nanoseconds) -> Self { + let is_neg = ns.high < 0; + let ns_high_abs = ns.high.unsigned_abs() as u128; + // Stick them together + let total = ((ns_high_abs << 64) + ns.low as u128) as i128; + // Reintroduce the sign + if is_neg { + -total + } else { + total + } + } +} + +impl From for ffi::I128Nanoseconds { + fn from(ns: i128) -> Self { + let is_neg = ns < 0; + let ns = ns.unsigned_abs(); + + let high = (ns >> 64) as i64; + let low = (ns & u64::MAX as u128) as u64; + let high = if is_neg { -high } else { high }; + + ffi::I128Nanoseconds { high, low } + } +} diff --git a/temporal_capi/src/lib.rs b/temporal_capi/src/lib.rs index bda121bd7..c2e403f65 100644 --- a/temporal_capi/src/lib.rs +++ b/temporal_capi/src/lib.rs @@ -29,5 +29,6 @@ pub mod plain_date_time; pub mod plain_month_day; pub mod plain_time; pub mod plain_year_month; +pub mod zoned_date_time; pub mod time_zone; diff --git a/temporal_capi/src/options.rs b/temporal_capi/src/options.rs index b89bf5794..07e59c47d 100644 --- a/temporal_capi/src/options.rs +++ b/temporal_capi/src/options.rs @@ -92,6 +92,12 @@ pub mod ffi { HalfEven, } + #[diplomat::enum_convert(temporal_rs::provider::TransitionDirection)] + pub enum TransitionDirection { + Next, + Previous, + } + pub struct Precision { /// Sets the precision to minute precision. pub is_minute: bool, diff --git a/temporal_capi/src/time_zone.rs b/temporal_capi/src/time_zone.rs index 6b9b49409..5c5972d94 100644 --- a/temporal_capi/src/time_zone.rs +++ b/temporal_capi/src/time_zone.rs @@ -7,6 +7,7 @@ pub mod ffi { use core::str; #[diplomat::opaque] + #[diplomat::transparent_convert] pub struct TimeZone(pub temporal_rs::TimeZone); impl TimeZone { @@ -26,5 +27,10 @@ pub mod ffi { .map(|x| Box::new(TimeZone(x))) .map_err(Into::into) } + + #[cfg(feature = "compiled_data")] + pub fn is_valid(&self) -> bool { + self.0.is_valid() + } } } diff --git a/temporal_capi/src/zoned_date_time.rs b/temporal_capi/src/zoned_date_time.rs new file mode 100644 index 000000000..c5a28f1cb --- /dev/null +++ b/temporal_capi/src/zoned_date_time.rs @@ -0,0 +1,391 @@ +#[cfg(feature = "compiled_data")] +use crate::error::ffi::TemporalError; + +#[diplomat::bridge] +#[diplomat::abi_rename = "temporal_rs_{0}"] +#[diplomat::attr(auto, namespace = "temporal_rs")] +#[cfg(feature = "compiled_data")] +pub mod ffi { + use crate::calendar::ffi::AnyCalendarKind; + use crate::calendar::ffi::Calendar; + use crate::duration::ffi::Duration; + use crate::error::ffi::TemporalError; + use crate::plain_date::ffi::{PartialDate, PlainDate}; + use crate::plain_date_time::ffi::PlainDateTime; + use crate::plain_time::ffi::{PartialTime, PlainTime}; + use alloc::boxed::Box; + + use crate::instant::ffi::I128Nanoseconds; + use crate::instant::ffi::Instant; + use crate::options::ffi::{ + ArithmeticOverflow, DifferenceSettings, Disambiguation, DisplayCalendar, DisplayOffset, + DisplayTimeZone, OffsetDisambiguation, RoundingOptions, ToStringRoundingOptions, + TransitionDirection, + }; + + use crate::time_zone::ffi::TimeZone; + + use alloc::string::String; + use core::fmt::Write; + + use diplomat_runtime::DiplomatOption; + use diplomat_runtime::DiplomatStrSlice; + use diplomat_runtime::DiplomatWrite; + + pub struct PartialZonedDateTime<'a> { + pub date: PartialDate<'a>, + pub time: PartialTime, + pub offset: DiplomatOption>, + pub timezone: Option<&'a TimeZone>, + } + #[diplomat::opaque] + pub struct ZonedDateTime(pub(crate) temporal_rs::ZonedDateTime); + + impl ZonedDateTime { + pub fn try_new( + nanosecond: I128Nanoseconds, + calendar: AnyCalendarKind, + time_zone: &TimeZone, + ) -> Result, TemporalError> { + temporal_rs::ZonedDateTime::try_new( + nanosecond.into(), + temporal_rs::Calendar::new(calendar.into()), + time_zone.0.clone(), + ) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn from_partial( + partial: PartialZonedDateTime, + overflow: Option, + disambiguation: Option, + offset_option: Option, + ) -> Result, TemporalError> { + temporal_rs::ZonedDateTime::from_partial( + partial.try_into()?, + overflow.map(Into::into), + disambiguation.map(Into::into), + offset_option.map(Into::into), + ) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn from_utf8( + s: &DiplomatStr, + disambiguation: Disambiguation, + offset_disambiguation: OffsetDisambiguation, + ) -> Result, TemporalError> { + // TODO(#275) This should not need to check + let s = core::str::from_utf8(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::ZonedDateTime::from_str( + s, + disambiguation.into(), + offset_disambiguation.into(), + ) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn from_utf16( + s: &DiplomatStr16, + disambiguation: Disambiguation, + offset_disambiguation: OffsetDisambiguation, + ) -> Result, TemporalError> { + // TODO(#275) This should not need to convert + let s = String::from_utf16(s).map_err(|_| temporal_rs::TemporalError::range())?; + temporal_rs::ZonedDateTime::from_str( + &s, + disambiguation.into(), + offset_disambiguation.into(), + ) + .map(|c| Box::new(Self(c))) + .map_err(Into::into) + } + + pub fn epoch_milliseconds(&self) -> i64 { + self.0.epoch_milliseconds() + } + + pub fn epoch_nanoseconds(&self) -> I128Nanoseconds { + self.0.epoch_nanoseconds().as_i128().into() + } + + pub fn to_instant(&self) -> Box { + Box::new(Instant(self.0.to_instant())) + } + + pub fn with( + &self, + partial: PartialZonedDateTime, + disambiguation: Option, + offset_option: Option, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .with( + partial.try_into()?, + disambiguation.map(Into::into), + offset_option.map(Into::into), + overflow.map(Into::into), + ) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn with_timezone(&self, zone: &TimeZone) -> Result, TemporalError> { + self.0 + .with_timezone(zone.0.clone()) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn timezone<'a>(&'a self) -> &'a TimeZone { + TimeZone::transparent_convert(self.0.timezone()) + } + + pub fn compare_instant(&self, other: &Self) -> core::cmp::Ordering { + self.0.compare_instant(&other.0) + } + + pub fn get_time_zone_transition( + &self, + direction: TransitionDirection, + ) -> Result>, TemporalError> { + self.0 + .get_time_zone_transition(direction.into()) + .map(|x| x.map(|y| Box::new(ZonedDateTime(y)))) + .map_err(Into::into) + } + + pub fn hours_in_day(&self) -> Result { + self.0.hours_in_day().map_err(Into::into) + } + + pub fn to_plain_datetime(&self) -> Result, TemporalError> { + self.0 + .to_plain_datetime() + .map(|x| Box::new(PlainDateTime(x))) + .map_err(Into::into) + } + + pub fn to_plain_date(&self) -> Result, TemporalError> { + self.0 + .to_plain_date() + .map(|x| Box::new(PlainDate(x))) + .map_err(Into::into) + } + + pub fn to_plain_time(&self) -> Result, TemporalError> { + self.0 + .to_plain_time() + .map(|x| Box::new(PlainTime(x))) + .map_err(Into::into) + } + + pub fn to_ixdtf_string( + &self, + display_offset: DisplayOffset, + display_timezone: DisplayTimeZone, + display_calendar: DisplayCalendar, + options: ToStringRoundingOptions, + + write: &mut DiplomatWrite, + ) -> Result<(), TemporalError> { + // TODO this double-allocates, an API returning a Writeable or impl Write would be better + let string = self.0.to_ixdtf_string( + display_offset.into(), + display_timezone.into(), + display_calendar.into(), + options.into(), + )?; + // throw away the error, this should always succeed + let _ = write.write_str(&string); + Ok(()) + } + + // Same as PlainDateTime (non-getters) + + pub fn with_calendar(&self, calendar: AnyCalendarKind) -> Result, TemporalError> { + self.0 + .with_calendar(temporal_rs::Calendar::new(calendar.into())) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn with_plain_time(&self, time: &PlainTime) -> Result, TemporalError> { + self.0 + .with_plain_time(time.0) + .map(|x| Box::new(ZonedDateTime(x))) + .map_err(Into::into) + } + + pub fn add( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .add(&duration.0, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn subtract( + &self, + duration: &Duration, + overflow: Option, + ) -> Result, TemporalError> { + self.0 + .subtract(&duration.0, overflow.map(Into::into)) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + pub fn until( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .until(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + pub fn since( + &self, + other: &Self, + settings: DifferenceSettings, + ) -> Result, TemporalError> { + self.0 + .since(&other.0, settings.try_into()?) + .map(|x| Box::new(Duration(x))) + .map_err(Into::into) + } + + pub fn round(&self, options: RoundingOptions) -> Result, TemporalError> { + self.0 + .round(options.try_into()?) + .map(|x| Box::new(Self(x))) + .map_err(Into::into) + } + + // Same as PlainDateTime (getters) + + pub fn hour(&self) -> u8 { + // unwrap_or_default because of + // https://github.com/boa-dev/temporal/issues/328 + self.0.hour().unwrap_or_default() + } + + pub fn minute(&self) -> u8 { + self.0.minute().unwrap_or_default() + } + + pub fn second(&self) -> u8 { + self.0.second().unwrap_or_default() + } + + pub fn millisecond(&self) -> u16 { + self.0.millisecond().unwrap_or_default() + } + + pub fn microsecond(&self) -> u16 { + self.0.microsecond().unwrap_or_default() + } + + pub fn nanosecond(&self) -> u16 { + self.0.nanosecond().unwrap_or_default() + } + + pub fn calendar<'a>(&'a self) -> &'a Calendar { + Calendar::transparent_convert(self.0.calendar()) + } + + pub fn year(&self) -> i32 { + self.0.year().unwrap_or_default() + } + + pub fn month(&self) -> u8 { + self.0.month().unwrap_or_default() + } + + pub fn month_code(&self, write: &mut DiplomatWrite) { + // https://github.com/boa-dev/temporal/issues/328 for the fallibility + let Ok(code) = self.0.month_code() else { + return; + }; + // throw away the error, this should always succeed + let _ = write.write_str(code.as_str()); + } + + pub fn day(&self) -> u8 { + self.0.day().unwrap_or_default() + } + + pub fn day_of_week(&self) -> Result { + self.0.day_of_week().map_err(Into::into) + } + + pub fn day_of_year(&self) -> u16 { + self.0.day_of_year().unwrap_or_default() + } + + pub fn week_of_year(&self) -> Option { + self.0.week_of_year().unwrap_or_default() + } + + pub fn year_of_week(&self) -> Option { + self.0.year_of_week().unwrap_or_default() + } + + pub fn days_in_week(&self) -> Result { + self.0.days_in_week().map_err(Into::into) + } + + pub fn days_in_month(&self) -> u16 { + self.0.days_in_month().unwrap_or_default() + } + + pub fn days_in_year(&self) -> u16 { + self.0.days_in_year().unwrap_or_default() + } + + pub fn months_in_year(&self) -> u16 { + self.0.months_in_year().unwrap_or_default() + } + + pub fn in_leap_year(&self) -> bool { + self.0.in_leap_year().unwrap_or_default() + } + // Writes an empty string for no era + + pub fn era(&self, write: &mut DiplomatWrite) { + let era = self.0.era().unwrap_or_default(); + if let Some(era) = era { + // throw away the error, this should always succeed + let _ = write.write_str(&era); + } + } + + pub fn era_year(&self) -> Option { + self.0.era_year().unwrap_or_default() + } + } +} + +#[cfg(feature = "compiled_data")] +impl TryFrom> for temporal_rs::partial::PartialZonedDateTime { + type Error = TemporalError; + fn try_from(other: ffi::PartialZonedDateTime<'_>) -> Result { + let offset = match other.offset.into_option() { + Some(o) => Some(temporal_rs::UtcOffset::from_utf8(o.into())?), + None => None, + }; + Ok(Self { + date: other.date.try_into()?, + time: other.time.into(), + offset, + timezone: other.timezone.map(|x| x.0.clone()), + }) + } +}