Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/intl/l10n/rust/fluent-ffi/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 10 kB image not shown  

Quelle  builtins.rs

  Sprache: Rust
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


use crate::ffi;
use fluent::types::{FluentNumberOptions, FluentType, FluentValue};
use fluent::FluentArgs;
use intl_memoizer::IntlLangMemoizer;
use intl_memoizer::Memoizable;
use nsstring::nsCString;
use std::borrow::Cow;
use std::ptr::NonNull;
use unic_langid::LanguageIdentifier;

pub struct NumberFormat {
    raw: Option<NonNull<ffi::RawNumberFormatter>>,
}

/**
 * According to http://userguide.icu-project.org/design, as long as we constrain
 * ourselves to const APIs ICU is const-correct.
 */

unsafe impl Send for NumberFormat {}
unsafe impl Sync for NumberFormat {}

impl NumberFormat {
    pub fn new(locale: LanguageIdentifier, options: &FluentNumberOptions) -> Self {
        let loc: String = locale.to_string();
        Self {
            raw: unsafe {
                NonNull::new(ffi::FluentBuiltInNumberFormatterCreate(
                    &loc.into(),
                    &options.into(),
                ))
            },
        }
    }

    pub fn format(&self, input: f64) -> String {
        if let Some(raw) = self.raw {
            unsafe {
                let mut byte_count = 0;
                let mut capacity = 0;
                let buffer = ffi::FluentBuiltInNumberFormatterFormat(
                    raw.as_ptr(),
                    input,
                    &mut byte_count,
                    &mut capacity,
                );
                if buffer.is_null() {
                    return String::new();
                }
                String::from_raw_parts(buffer, byte_count, capacity)
            }
        } else {
            String::new()
        }
    }
}

impl Drop for NumberFormat {
    fn drop(&mut self) {
        if let Some(raw) = self.raw {
            unsafe { ffi::FluentBuiltInNumberFormatterDestroy(raw.as_ptr()) };
        }
    }
}

impl Memoizable for NumberFormat {
    type Args = (FluentNumberOptions,);
    type Error = &'static str;
    fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<SelfSelf::Error> {
        Ok(NumberFormat::new(lang, &args.0))
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum FluentDateTimeStyle {
    Full,
    Long,
    Medium,
    Short,
    None,
}

impl Default for FluentDateTimeStyle {
    fn default() -> Self {
        Self::None
    }
}

impl From<&str> for FluentDateTimeStyle {
    fn from(input: &str) -> Self {
        match input {
            "full" => Self::Full,
            "long" => Self::Long,
            "medium" => Self::Medium,
            "short" => Self::Short,
            _ => Self::None,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum FluentDateTimeHourCycle {
    H24,
    H23,
    H12,
    H11,
    None,
}

impl Default for FluentDateTimeHourCycle {
    fn default() -> Self {
        Self::None
    }
}

impl From<&str> for FluentDateTimeHourCycle {
    fn from(input: &str) -> Self {
        match input {
            "h24" => Self::H24,
            "h23" => Self::H23,
            "h12" => Self::H12,
            "h11" => Self::H11,
            _ => Self::None,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum FluentDateTimeTextComponent {
    Long,
    Short,
    Narrow,
    None,
}

impl Default for FluentDateTimeTextComponent {
    fn default() -> Self {
        Self::None
    }
}

impl From<&str> for FluentDateTimeTextComponent {
    fn from(input: &str) -> Self {
        match input {
            "long" => Self::Long,
            "short" => Self::Short,
            "narrow" => Self::Narrow,
            _ => Self::None,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum FluentDateTimeNumericComponent {
    Numeric,
    TwoDigit,
    None,
}

impl Default for FluentDateTimeNumericComponent {
    fn default() -> Self {
        Self::None
    }
}

impl From<&str> for FluentDateTimeNumericComponent {
    fn from(input: &str) -> Self {
        match input {
            "numeric" => Self::Numeric,
            "2-digit" => Self::TwoDigit,
            _ => Self::None,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum FluentDateTimeMonthComponent {
    Numeric,
    TwoDigit,
    Long,
    Short,
    Narrow,
    None,
}

impl Default for FluentDateTimeMonthComponent {
    fn default() -> Self {
        Self::None
    }
}

impl From<&str> for FluentDateTimeMonthComponent {
    fn from(input: &str) -> Self {
        match input {
            "numeric" => Self::Numeric,
            "2-digit" => Self::TwoDigit,
            "long" => Self::Long,
            "short" => Self::Short,
            "narrow" => Self::Narrow,
            _ => Self::None,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum FluentDateTimeTimeZoneNameComponent {
    Long,
    Short,
    None,
}

impl Default for FluentDateTimeTimeZoneNameComponent {
    fn default() -> Self {
        Self::None
    }
}

impl From<&str> for FluentDateTimeTimeZoneNameComponent {
    fn from(input: &str) -> Self {
        match input {
            "long" => Self::Long,
            "short" => Self::Short,
            _ => Self::None,
        }
    }
}

#[repr(C)]
#[derive(Default, Debug, Clone, Hash, PartialEq, Eq)]
pub struct FluentDateTimeOptions {
    pub date_style: FluentDateTimeStyle,
    pub time_style: FluentDateTimeStyle,
    pub hour_cycle: FluentDateTimeHourCycle,
    pub weekday: FluentDateTimeTextComponent,
    pub era: FluentDateTimeTextComponent,
    pub year: FluentDateTimeNumericComponent,
    pub month: FluentDateTimeMonthComponent,
    pub day: FluentDateTimeNumericComponent,
    pub hour: FluentDateTimeNumericComponent,
    pub minute: FluentDateTimeNumericComponent,
    pub second: FluentDateTimeNumericComponent,
    pub time_zone_name: FluentDateTimeTimeZoneNameComponent,
}

impl FluentDateTimeOptions {
    pub fn merge(&mut self, opts: &FluentArgs) {
        for (key, value) in opts.iter() {
            match (key, value) {
                ("dateStyle", FluentValue::String(n)) => {
                    self.date_style = n.as_ref().into();
                }
                ("timeStyle", FluentValue::String(n)) => {
                    self.time_style = n.as_ref().into();
                }
                ("hourCycle", FluentValue::String(n)) => {
                    self.hour_cycle = n.as_ref().into();
                }
                ("weekday", FluentValue::String(n)) => {
                    self.weekday = n.as_ref().into();
                }
                ("era", FluentValue::String(n)) => {
                    self.era = n.as_ref().into();
                }
                ("year", FluentValue::String(n)) => {
                    self.year = n.as_ref().into();
                }
                ("month", FluentValue::String(n)) => {
                    self.month = n.as_ref().into();
                }
                ("day", FluentValue::String(n)) => {
                    self.day = n.as_ref().into();
                }
                ("hour", FluentValue::String(n)) => {
                    self.hour = n.as_ref().into();
                }
                ("minute", FluentValue::String(n)) => {
                    self.minute = n.as_ref().into();
                }
                ("second", FluentValue::String(n)) => {
                    self.second = n.as_ref().into();
                }
                ("timeZoneName", FluentValue::String(n)) => {
                    self.time_zone_name = n.as_ref().into();
                }
                _ => {}
            }
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct FluentDateTime {
    epoch: f64,
    options: FluentDateTimeOptions,
}

impl FluentType for FluentDateTime {
    fn duplicate(&self) -> Box<dyn FluentType + Send> {
        Box::new(self.clone())
    }
    fn as_string(&self, intls: &IntlLangMemoizer) -> Cow<'static, str> {
        let result = intls
            .with_try_get::<DateTimeFormat, _, _>((self.options.clone(),), |dtf| {
                dtf.format(self.epoch)
            })
            .expect("Failed to retrieve a DateTimeFormat instance.");
        result.into()
    }
    fn as_string_threadsafe(
        &self,
        _: &intl_memoizer::concurrent::IntlLangMemoizer,
    ) -> Cow<'static, str> {
        unimplemented!()
    }
}

impl std::fmt::Display for FluentDateTime {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "DATETIME: {}"self.epoch)
    }
}

impl FluentDateTime {
    pub fn new(epoch: f64, options: FluentDateTimeOptions) -> Self {
        Self { epoch, options }
    }
}

pub struct DateTimeFormat {
    raw: Option<NonNull<ffi::RawDateTimeFormatter>>,
}

/**
 * According to http://userguide.icu-project.org/design, as long as we constrain
 * ourselves to const APIs ICU is const-correct.
 */

unsafe impl Send for DateTimeFormat {}
unsafe impl Sync for DateTimeFormat {}

impl DateTimeFormat {
    pub fn new(locale: LanguageIdentifier, options: FluentDateTimeOptions) -> Self {
        // ICU needs null-termination here, otherwise we could use nsCStr.
        let loc: nsCString = locale.to_string().into();
        Self {
            raw: unsafe { NonNull::new(ffi::FluentBuiltInDateTimeFormatterCreate(&loc, options)) },
        }
    }

    pub fn format(&self, input: f64) -> String {
        if let Some(raw) = self.raw {
            unsafe {
                let mut byte_count = 0;
                let buffer =
                    ffi::FluentBuiltInDateTimeFormatterFormat(raw.as_ptr(), input, &mut byte_count);
                if buffer.is_null() {
                    return String::new();
                }
                String::from_raw_parts(buffer, byte_count as usize, byte_count as usize)
            }
        } else {
            String::new()
        }
    }
}

impl Drop for DateTimeFormat {
    fn drop(&mut self) {
        if let Some(raw) = self.raw {
            unsafe { ffi::FluentBuiltInDateTimeFormatterDestroy(raw.as_ptr()) };
        }
    }
}

impl Memoizable for DateTimeFormat {
    type Args = (FluentDateTimeOptions,);
    type Error = &'static str;
    fn construct(lang: LanguageIdentifier, args: Self::Args) -> Result<SelfSelf::Error> {
        Ok(DateTimeFormat::new(lang, args.0))
    }
}

Messung V0.5 in Prozent
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.