// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

// @generated by tools/make/codegen/src/capi_datetime.rs

#[rustfmt::skip]
#[diplomat::bridge]
#[diplomat::abi_rename = "icu4x_{0}_mv1"]
pub mod ffi {
    use alloc::boxed::Box;
    use icu_calendar::Gregorian;
    use writeable::TryWriteable;

    #[allow(unused_imports)]
    use crate::datetime_helpers::{self, map_or_default};

    #[allow(unused_imports)]
    use crate::unstable::{
        date_formatter::ffi::{DateFormatter, DateFormatterGregorian},
        date_time_formatter::ffi::{DateTimeFormatter, DateTimeFormatterGregorian},
        date::ffi::{Date, IsoDate},
        datetime_options::ffi::{DateTimeAlignment, DateTimeLength, TimePrecision},
        errors::ffi::DateTimeFormatterLoadError,
        errors::ffi::DateTimeWriteError,
        locale_core::ffi::Locale,
        time_formatter::ffi::TimeFormatter,
        time::ffi::Time,
        timezone::ffi::TimeZoneInfo,
    };

    #[cfg(feature = "buffer_provider")]
    use crate::unstable::provider::ffi::DataProvider;

    #[diplomat::opaque]
    #[diplomat::rust_link(icu::datetime::DateTimeFormatter, Struct)]
    pub struct ZonedDateFormatter(
        pub  icu_datetime::DateTimeFormatter<
            icu_datetime::fieldsets::enums::ZonedDateFieldSet
        >,
    );

    impl ZonedDateFormatter {
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_long")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[diplomat::demo(default_constructor)]
        #[cfg(feature = "compiled_data")]
        pub fn create_specific_long(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::SpecificLong;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_specific_long_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_long_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_specific_long_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::SpecificLong;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_specific_long_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_short")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_specific_short(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::SpecificShort;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_specific_short_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_short_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_specific_short_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::SpecificShort;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_specific_short_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_long")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_localized_offset_long(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetLong;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_localized_offset_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_long_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_localized_offset_long_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetLong;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_localized_offset_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_short")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_localized_offset_short(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetShort;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_localized_offset_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_short_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_localized_offset_short_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetShort;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_localized_offset_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_long")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_generic_long(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::GenericLong;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_generic_long_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_long_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_generic_long_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::GenericLong;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_generic_long_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_short")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_generic_short(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::GenericShort;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_generic_short_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_short_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_generic_short_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::GenericShort;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_generic_short_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "location")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::Location, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_location(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::Location;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_location_names(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "location_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::Location, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_location_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::Location;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_location_names(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "exemplar_city")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::ExemplarCity, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_exemplar_city(
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::ExemplarCity;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .as_mut()
                        .include_time_zone_exemplar_city_names(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "exemplar_city_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::ExemplarCity, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_exemplar_city_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatter,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::ExemplarCity;
            datetime_helpers::date_formatter_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .as_mut()
                        .load_time_zone_exemplar_city_names(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        #[diplomat::rust_link(icu::datetime::DateTimeFormatter::format, FnInStruct)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime::to_string, FnInStruct, hidden)]
        pub fn format_iso(
            &self,
            iso_date: &IsoDate,
            zone: &TimeZoneInfo,
            write: &mut diplomat_runtime::DiplomatWrite,
        ) -> Result<(), DateTimeWriteError> {
            let mut input = icu_datetime::unchecked::DateTimeInputUnchecked::default();
            let date_in_calendar = iso_date.0.to_calendar(self.0.calendar());
            input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
            input.set_time_zone_info_at_time_fields(zone.as_rust_at_time(Some(iso_date.0), None));

            self
                .0
                .format_unchecked(input)
                .try_write_to(write)
                .ok()
                .transpose()?;
            Ok(())
        }
        
        #[diplomat::rust_link(icu::datetime::DateTimeFormatter::format_same_calendar, FnInStruct)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime::to_string, FnInStruct, hidden)]
        #[diplomat::attr(demo_gen, disable)] // confusing, as Date is constructed from ISO
        pub fn format_same_calendar(
            &self,
            date: &Date,
            zone: &TimeZoneInfo,
            write: &mut diplomat_runtime::DiplomatWrite,
        ) -> Result<(), crate::unstable::errors::ffi::DateTimeMismatchedCalendarError> {
            let date_borrowed = date.0.as_borrowed();
            // Check that the date's calendar matches the formatter's calendar
            use icu_datetime::scaffold::InSameCalendar;
            date_borrowed.check_any_calendar_kind(self.0.calendar().kind()).map_err(crate::unstable::errors::ffi::DateTimeMismatchedCalendarError::from)?;
            let mut input = icu_datetime::unchecked::DateTimeInputUnchecked::default();
            input.set_date_fields_unchecked(date_borrowed); // calendar check on previous lines
            input.set_time_zone_info_at_time_fields(zone.as_rust_at_time(Some(date.0.clone()), None));

            let _ = self
                .0
                .format_unchecked(input)
                .try_write_to(write);

            Ok(())
        }
    }
    

    #[diplomat::opaque]
    #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter, Struct)]
    pub struct ZonedDateFormatterGregorian(
        pub  icu_datetime::FixedCalendarDateTimeFormatter<
            Gregorian,
            icu_datetime::fieldsets::enums::ZonedDateFieldSet
        >,
    );

    impl ZonedDateFormatterGregorian {
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_long")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[diplomat::demo(default_constructor)]
        #[cfg(feature = "compiled_data")]
        pub fn create_specific_long(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::SpecificLong;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_specific_long_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_long_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_specific_long_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::SpecificLong;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_specific_long_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_short")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_specific_short(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::SpecificShort;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_specific_short_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "specific_short_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::SpecificShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_specific_short_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::SpecificShort;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_specific_short_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_long")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_localized_offset_long(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetLong;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_localized_offset_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_long_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_localized_offset_long_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetLong;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_localized_offset_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_short")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_localized_offset_short(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetShort;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_localized_offset_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "localized_offset_short_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::LocalizedOffsetShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_localized_offset_short_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::LocalizedOffsetShort;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_localized_offset_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_long")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_generic_long(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::GenericLong;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_generic_long_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_long_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericLong, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_generic_long_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::GenericLong;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_generic_long_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_short")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_generic_short(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::GenericShort;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_generic_short_names_with_fallback(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "generic_short_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::GenericShort, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_generic_short_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::GenericShort;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_generic_short_names_with_fallback(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "location")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::Location, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_location(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::Location;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_location_names(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "location_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::Location, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_location_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::Location;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_location_names(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "exemplar_city")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::ExemplarCity, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "compiled_data")]
        pub fn create_exemplar_city(
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let zone = icu_datetime::fieldsets::zone::ExemplarCity;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    names
                        .include_time_zone_exemplar_city_names(
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter(
                    field_set
                ),
            )
        }
        
        /// Creates a zoned formatter based on a non-zoned formatter.
        ///
        /// Caution: The locale provided here must match the locale used to construct the non-zoned formatter,
        /// or else unexpected behavior may occur!
        #[diplomat::attr(all(supports = fallible_constructors, supports = named_constructors), named_constructor = "exemplar_city_with_provider")]
        #[diplomat::rust_link(icu::datetime::fieldsets::zone::ExemplarCity, Struct)]
        #[diplomat::rust_link(icu::datetime::fieldsets::Combo, Struct, hidden)]
        #[cfg(feature = "buffer_provider")]
        pub fn create_exemplar_city_with_provider(
            provider: &DataProvider,
            locale: &Locale,
            formatter: &DateFormatterGregorian,
        ) -> Result<Box<Self>, DateTimeFormatterLoadError> {
            let provider = provider.get()?;
            let zone = icu_datetime::fieldsets::zone::ExemplarCity;
            datetime_helpers::date_formatter_gregorian_with_zone(
                &formatter.0,
                locale,
                zone,
                |names| {
                    use icu_provider::buf::AsDeserializingBufferProvider;
                    let provider = provider.as_deserializing();
                    names
                        .load_time_zone_exemplar_city_names(
                            &provider
                        )?;
                    Ok(())
                },
                #[allow(clippy::result_large_err)] // probably not an issue in a closure?
                |names, field_set| names.try_into_formatter_with_buffer_provider(
                    &provider,
                    field_set
                ),
            )
        }
        
        #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::format, FnInStruct)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime::to_string, FnInStruct, hidden)]
        pub fn format_iso(
            &self,
            iso_date: &IsoDate,
            zone: &TimeZoneInfo,
            write: &mut diplomat_runtime::DiplomatWrite,
        ) -> Result<(), DateTimeWriteError> {
            let mut input = icu_datetime::unchecked::DateTimeInputUnchecked::default();
            let date_in_calendar = iso_date.0.to_calendar(Gregorian);
            input.set_date_fields_unchecked(date_in_calendar); // calendar conversion on previous line
            input.set_time_zone_info_at_time_fields(zone.as_rust_at_time(Some(iso_date.0), None));

            self
                .0
                .format_unchecked(input)
                .try_write_to(write)
                .ok()
                .transpose()?;
            Ok(())
        }
        
        #[diplomat::rust_link(icu::datetime::FixedCalendarDateTimeFormatter::format_same_calendar, FnInStruct)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime, Struct, hidden)]
        #[diplomat::rust_link(icu::datetime::FormattedDateTime::to_string, FnInStruct, hidden)]
        #[diplomat::attr(demo_gen, disable)] // confusing, as Date is constructed from ISO
        pub fn format_same_calendar(
            &self,
            date: &Date,
            zone: &TimeZoneInfo,
            write: &mut diplomat_runtime::DiplomatWrite,
        ) -> Result<(), crate::unstable::errors::ffi::DateTimeMismatchedCalendarError> {
            let date_borrowed = date.0.as_borrowed();
            // Check that the date's calendar matches the formatter's calendar
            use icu_datetime::scaffold::InSameCalendar;
            date_borrowed.check_any_calendar_kind(icu_calendar::AnyCalendarKind::Gregorian).map_err(crate::unstable::errors::ffi::DateTimeMismatchedCalendarError::from)?;
            let mut input = icu_datetime::unchecked::DateTimeInputUnchecked::default();
            input.set_date_fields_unchecked(date_borrowed); // calendar check on previous lines
            input.set_time_zone_info_at_time_fields(zone.as_rust_at_time(Some(date.0.clone()), None));

            let _ = self
                .0
                .format_unchecked(input)
                .try_write_to(write);

            Ok(())
        }
    }
    
}
