#![allow(clippy::exhaustive_structs, clippy::exhaustive_enums)]
use icu_provider::prelude::*;
use num_bigint::BigInt;
use zerotrie::ZeroTrieSimpleAscii;
use zerovec::{ule::AsULE, VarZeroVec, ZeroVec};
use crate::measure::provider::single_unit::SingleUnit;
#[cfg(feature = "compiled_data")]
pub use crate::provider::Baked;
use super::ratio::IcuRatio;
#[icu_provider::data_struct(marker(UnitsInfoV1Marker, "units/info@1", singleton))]
#[derive(Clone, PartialEq, Debug)]
#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_experimental::units::provider))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
pub struct UnitsInfoV1<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub units_conversion_trie: ZeroTrieSimpleAscii<ZeroVec<'data, u8>>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub convert_infos: VarZeroVec<'data, ConversionInfoULE>,
}
#[zerovec::make_varule(ConversionInfoULE)]
#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Default)]
#[cfg_attr(feature = "datagen", derive(databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_experimental::units::provider))]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize),
zerovec::derive(Serialize)
)]
#[cfg_attr(
feature = "serde",
derive(serde::Deserialize),
zerovec::derive(Deserialize)
)]
#[zerovec::derive(Debug)]
pub struct ConversionInfo<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub basic_units: ZeroVec<'data, SingleUnit>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub factor_num: ZeroVec<'data, u8>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub factor_den: ZeroVec<'data, u8>,
pub factor_sign: Sign,
#[cfg_attr(feature = "serde", serde(borrow))]
pub offset_num: ZeroVec<'data, u8>,
#[cfg_attr(feature = "serde", serde(borrow))]
pub offset_den: ZeroVec<'data, u8>,
pub offset_sign: Sign,
pub exactness: Exactness,
}
#[zerovec::make_ule(SignULE)]
#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_experimental::units::provider))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum Sign {
#[default]
Positive = 0,
Negative = 1,
}
#[zerovec::make_ule(ExactnessULE)]
#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_experimental::units::provider))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Default)]
#[repr(u8)]
pub enum Exactness {
#[default]
Exact = 0,
Approximate = 1,
}
impl ConversionInfoULE {
pub(crate) fn factor_as_ratio(&self) -> IcuRatio {
let sign: num_bigint::Sign = Sign::from_unaligned(self.factor_sign).into();
IcuRatio::from_big_ints(
BigInt::from_bytes_le(sign, self.factor_num().as_ule_slice()),
BigInt::from_bytes_le(num_bigint::Sign::Plus, self.factor_den().as_ule_slice()),
)
}
pub(crate) fn offset_as_ratio(&self) -> IcuRatio {
let sign: num_bigint::Sign = Sign::from_unaligned(self.offset_sign).into();
IcuRatio::from_big_ints(
BigInt::from_bytes_le(sign, self.offset_num().as_ule_slice()),
BigInt::from_bytes_le(num_bigint::Sign::Plus, self.offset_den().as_ule_slice()),
)
}
}