Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/intl/l10n/rust/fluent-ffi/src/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 4 kB image not shown  

Quelle  text_elements.rs   Sprache: unbekannt

 
/* 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 fluent::FluentResource;
use fluent_syntax::ast;
use nsstring::nsCString;
use thin_vec::ThinVec;

#[repr(C)]
pub struct TextElementInfo {
    id: nsCString,
    attr: nsCString,
    text: nsCString,
}

struct TextElementsCollector<'a> {
    current_id: Option<String>,
    current_attr: Option<String>,
    elements: &'a mut ThinVec<TextElementInfo>,
}

impl<'a> TextElementsCollector<'a> {
    pub fn new(elements: &'a mut ThinVec<TextElementInfo>) -> Self {
        Self {
            current_id: None,
            current_attr: None,
            elements,
        }
    }

    fn collect_inline_expression(&mut self, x: &ast::InlineExpression<&str>) {
        match x {
            ast::InlineExpression::StringLiteral { .. } => {}
            ast::InlineExpression::NumberLiteral { .. } => {}
            ast::InlineExpression::FunctionReference { arguments, .. } => {
                self.collect_call_arguments(arguments);
            }
            ast::InlineExpression::MessageReference { .. } => {}
            ast::InlineExpression::TermReference { arguments, .. } => {
                if let Some(y) = arguments {
                    self.collect_call_arguments(y);
                }
            }
            ast::InlineExpression::VariableReference { .. } => {}
            ast::InlineExpression::Placeable { expression } => {
                self.collect_expression(expression.as_ref());
            }
        }
    }

    fn collect_named_argument(&mut self, x: &ast::NamedArgument<&str>) {
        self.collect_inline_expression(&x.value);
    }

    fn collect_call_arguments(&mut self, x: &ast::CallArguments<&str>) {
        for y in x.positional.iter() {
            self.collect_inline_expression(y);
        }
        for y in x.named.iter() {
            self.collect_named_argument(y);
        }
    }

    fn collect_variant(&mut self, x: &ast::Variant<&str>) {
        self.collect_pattern(&x.value);
    }

    fn collect_expression(&mut self, x: &ast::Expression<&str>) {
        match x {
            ast::Expression::Select { selector, variants } => {
                self.collect_inline_expression(selector);
                for y in variants.iter() {
                    self.collect_variant(y);
                }
            }
            ast::Expression::Inline(i) => {
                self.collect_inline_expression(i);
            }
        }
    }

    fn collect_pattern_element(&mut self, x: &ast::PatternElement<&str>) {
        match x {
            ast::PatternElement::TextElement { value } => {
                self.elements.push(TextElementInfo {
                    id: self
                        .current_id
                        .as_ref()
                        .map_or_else(nsCString::new, nsCString::from),
                    attr: self
                        .current_attr
                        .as_ref()
                        .map_or_else(nsCString::new, nsCString::from),
                    text: nsCString::from(*value),
                });
            }
            ast::PatternElement::Placeable { expression } => {
                self.collect_expression(expression);
            }
        }
    }

    fn collect_pattern(&mut self, x: &ast::Pattern<&str>) {
        for y in x.elements.iter() {
            self.collect_pattern_element(y);
        }
    }

    fn collect_attribute(&mut self, x: &ast::Attribute<&str>) {
        self.current_attr = Some(x.id.name.to_string());

        self.collect_pattern(&x.value);
    }

    fn collect_message(&mut self, x: &ast::Message<&str>) {
        self.current_id = Some(x.id.name.to_string());
        self.current_attr = None;

        if let Some(ref y) = x.value {
            self.collect_pattern(y);
        }
        for y in x.attributes.iter() {
            self.collect_attribute(y);
        }
    }

    fn collect_term(&mut self, x: &ast::Term<&str>) {
        self.current_id = Some(x.id.name.to_string());
        self.current_attr = None;

        self.collect_pattern(&x.value);
        for y in x.attributes.iter() {
            self.collect_attribute(y);
        }
    }

    pub fn collect_entry(&mut self, x: &ast::Entry<&str>) {
        match x {
            ast::Entry::Message(m) => {
                self.collect_message(m);
            }
            ast::Entry::Term(t) => {
                self.collect_term(t);
            }
            ast::Entry::Comment(_) => {}
            ast::Entry::GroupComment(_) => {}
            ast::Entry::ResourceComment(_) => {}
            ast::Entry::Junk { .. } => {}
        }
    }
}

#[no_mangle]
pub extern "C" fn fluent_resource_get_text_elements(
    res: &FluentResource,
    elements: &mut ThinVec<TextElementInfo>,
) {
    let mut collector = TextElementsCollector::new(elements);

    for entry in res.entries() {
        collector.collect_entry(entry);
    }
}

[ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ]