FIX: Don not clone Locales and Languages, pass them by reference

This commit is contained in:
Nicolás Hatcher
2025-12-14 16:55:14 +01:00
parent ffe5d1a158
commit 96a5482e01
84 changed files with 308 additions and 251 deletions

View File

@@ -79,19 +79,24 @@ pub enum LexerMode {
/// Tokenize an input
#[derive(Clone)]
pub struct Lexer {
pub struct Lexer<'a> {
position: usize,
next_token_position: Option<usize>,
len: usize,
chars: Vec<char>,
mode: LexerMode,
locale: Locale,
language: Language,
locale: &'a Locale,
language: &'a Language,
}
impl Lexer {
impl<'a> Lexer<'a> {
/// Creates a new `Lexer` that returns the tokens of a formula.
pub fn new(formula: &str, mode: LexerMode, locale: &Locale, language: &Language) -> Lexer {
pub fn new(
formula: &str,
mode: LexerMode,
locale: &'a Locale,
language: &'a Language,
) -> Lexer<'a> {
let chars: Vec<char> = formula.chars().collect();
let len = chars.len();
Lexer {
@@ -100,8 +105,8 @@ impl Lexer {
next_token_position: None,
len,
mode,
locale: locale.clone(),
language: language.clone(),
locale,
language,
}
}
@@ -111,13 +116,13 @@ impl Lexer {
}
/// Sets the locale
pub fn set_locale(&mut self, locale: &Locale) {
self.locale = locale.clone();
pub fn set_locale(&mut self, locale: &'a Locale) {
self.locale = locale;
}
/// Sets the language
pub fn set_language(&mut self, language: &Language) {
self.language = language.clone();
pub fn set_language(&mut self, language: &'a Language) {
self.language = language;
}
// FIXME: I don't think we should have `is_a1_mode` and `get_formula`.

View File

@@ -4,7 +4,7 @@ use crate::expressions::{token::TokenType, utils::column_to_number};
use super::Lexer;
use super::{ParsedRange, ParsedReference, Result};
impl Lexer {
impl<'a> Lexer<'a> {
/// Consumes a reference in A1 style like:
/// AS23, $AS23, AS$23, $AS$23, R12
/// Or returns an error

View File

@@ -16,7 +16,7 @@ use crate::expressions::token::{TableReference, TableSpecifier};
use super::Result;
use super::{Lexer, LexerError};
impl Lexer {
impl<'a> Lexer<'a> {
fn consume_table_specifier(&mut self) -> Result<Option<TableSpecifier>> {
if self.peek_char() == Some('#') {
// It's a specifier

View File

@@ -11,7 +11,7 @@ use crate::expressions::{
types::ParsedReference,
};
fn new_lexer(formula: &str, a1_mode: bool) -> Lexer {
fn new_lexer(formula: &str, a1_mode: bool) -> Lexer<'_> {
let locale = get_locale("en").unwrap();
let language = get_language("en").unwrap();
let mode = if a1_mode {
@@ -655,7 +655,9 @@ fn test_comma() {
// Used for testing locales where the comma is the decimal separator
let mut lx = new_lexer("12,34", false);
lx.locale.numbers.symbols.decimal = ",".to_string();
let locale = get_locale("de").unwrap();
lx.locale = locale;
assert_eq!(lx.next_token(), Number(12.34));
assert_eq!(lx.next_token(), EOF);
}

View File

@@ -7,7 +7,7 @@ use crate::expressions::{
use crate::language::get_language;
use crate::locale::get_locale;
fn new_lexer(formula: &str) -> Lexer {
fn new_lexer(formula: &str) -> Lexer<'_> {
let locale = get_locale("en").unwrap();
let language = get_language("en").unwrap();
Lexer::new(formula, LexerMode::A1, locale, language)

View File

@@ -6,11 +6,11 @@ use crate::{
token::{Error, TokenType},
},
language::get_language,
locale::get_locale,
locale::get_default_locale,
};
fn new_language_lexer(formula: &str, language: &str) -> Lexer {
let locale = get_locale("en").unwrap();
fn new_language_lexer<'a>(formula: &str, language: &str) -> Lexer<'a> {
let locale = get_default_locale();
let language = get_language(language).unwrap();
Lexer::new(formula, LexerMode::A1, locale, language)
}

View File

@@ -9,7 +9,7 @@ use crate::{
locale::get_locale,
};
fn new_language_lexer(formula: &str, locale: &str, language: &str) -> Lexer {
fn new_language_lexer<'a>(formula: &str, locale: &str, language: &str) -> Lexer<'a> {
let locale = get_locale(locale).unwrap();
let language = get_language(language).unwrap();
Lexer::new(formula, LexerMode::A1, locale, language)

View File

@@ -10,7 +10,7 @@ use crate::expressions::{
use crate::language::get_language;
use crate::locale::get_locale;
fn new_lexer(formula: &str) -> Lexer {
fn new_lexer(formula: &str) -> Lexer<'_> {
let locale = get_locale("en").unwrap();
let language = get_language("en").unwrap();
Lexer::new(formula, LexerMode::A1, locale, language)

View File

@@ -7,7 +7,7 @@ use crate::expressions::{
use crate::language::get_language;
use crate::locale::get_locale;
fn new_lexer(formula: &str) -> Lexer {
fn new_lexer(formula: &str) -> Lexer<'_> {
let locale = get_locale("en").unwrap();
let language = get_language("en").unwrap();
Lexer::new(formula, LexerMode::A1, locale, language)

View File

@@ -31,8 +31,10 @@ f_args => e (',' e)*
use std::collections::HashMap;
use crate::functions::Function;
use crate::language::get_default_language;
use crate::language::get_language;
use crate::language::Language;
use crate::locale::get_default_locale;
use crate::locale::get_locale;
use crate::locale::Locale;
use crate::types::Table;
@@ -204,34 +206,34 @@ pub enum Node {
}
#[derive(Clone)]
pub struct Parser {
lexer: lexer::Lexer,
pub struct Parser<'a> {
lexer: lexer::Lexer<'a>,
worksheets: Vec<String>,
defined_names: Vec<DefinedNameS>,
context: CellReferenceRC,
tables: HashMap<String, Table>,
locale: Locale,
language: Language,
locale: &'a Locale,
language: &'a Language,
}
pub fn new_parser_english(
pub fn new_parser_english<'a>(
worksheets: Vec<String>,
defined_names: Vec<DefinedNameS>,
tables: HashMap<String, Table>,
) -> Parser {
let locale = Locale::default();
let language = Language::default();
Parser::new(worksheets, defined_names, tables, &locale, &language)
) -> Parser<'a> {
let locale = get_default_locale();
let language = get_default_language();
Parser::new(worksheets, defined_names, tables, locale, language)
}
impl Parser {
impl<'a> Parser<'a> {
pub fn new(
worksheets: Vec<String>,
defined_names: Vec<DefinedNameS>,
tables: HashMap<String, Table>,
locale: &Locale,
language: &Language,
) -> Parser {
locale: &'a Locale,
language: &'a Language,
) -> Parser<'a> {
let lexer = lexer::Lexer::new("", lexer::LexerMode::A1, locale, language);
let context = CellReferenceRC {
sheet: worksheets.first().map_or("", |v| v).to_string(),
@@ -244,21 +246,21 @@ impl Parser {
defined_names,
context,
tables,
locale: locale.clone(),
language: language.clone(),
locale,
language,
}
}
pub fn set_lexer_mode(&mut self, mode: lexer::LexerMode) {
self.lexer.set_lexer_mode(mode)
}
pub fn set_locale(&mut self, locale: &Locale) {
self.locale = locale.clone();
pub fn set_locale(&mut self, locale: &'a Locale) {
self.locale = locale;
self.lexer.set_locale(locale);
}
pub fn set_language(&mut self, language: &Language) {
self.language = language.clone();
pub fn set_language(&mut self, language: &'a Language) {
self.language = language;
self.lexer.set_language(language);
}

View File

@@ -1,3 +1,5 @@
#![allow(clippy::unwrap_used)]
use std::collections::HashMap;
use crate::expressions::parser::{DefinedNameS, Node, Parser};
@@ -15,11 +17,11 @@ pub fn to_string(t: &Node, cell_reference: &CellReferenceRC) -> String {
to_localized_string(t, cell_reference, locale, language)
}
pub fn new_parser(
pub fn new_parser<'a>(
worksheets: Vec<String>,
defined_names: Vec<DefinedNameS>,
tables: HashMap<String, Table>,
) -> Parser {
) -> Parser<'a> {
let locale = get_locale("en").unwrap();
let language = get_language("es").unwrap();
Parser::new(worksheets, defined_names, tables, locale, language)

View File

@@ -4,13 +4,13 @@ use crate::expressions::parser::move_formula::{move_formula as mf, MoveContext};
use crate::expressions::parser::tests::utils::new_parser;
use crate::expressions::parser::Node;
use crate::expressions::types::{Area, CellReferenceRC};
use crate::language::Language;
use crate::locale::Locale;
use crate::language::get_default_language;
use crate::locale::get_default_locale;
fn move_formula(node: &Node, context: &MoveContext) -> String {
let locale = Locale::default();
let language = Language::default();
mf(node, context, &locale, &language)
let locale = get_default_locale();
let language = get_default_language();
mf(node, context, locale, language)
}
#[test]

View File

@@ -5,25 +5,25 @@ use crate::{
parser::{DefinedNameS, Node, Parser},
types::CellReferenceRC,
},
language::Language,
locale::Locale,
language::get_default_language,
locale::get_default_locale,
types::Table,
};
use crate::expressions::parser::stringify::to_localized_string;
pub fn to_english_localized_string(t: &Node, cell_reference: &CellReferenceRC) -> String {
let locale = Locale::default();
let language = Language::default();
to_localized_string(t, cell_reference, &locale, &language)
let locale = get_default_locale();
let language = get_default_language();
to_localized_string(t, cell_reference, locale, language)
}
pub fn new_parser(
pub fn new_parser<'a>(
worksheets: Vec<String>,
defined_names: Vec<DefinedNameS>,
tables: HashMap<String, Table>,
) -> Parser {
let locale = Locale::default();
let language = Language::default();
Parser::new(worksheets, defined_names, tables, &locale, &language)
) -> Parser<'a> {
let locale = get_default_locale();
let language = get_default_language();
Parser::new(worksheets, defined_names, tables, locale, language)
}