Skip to main content

bubbles/runtime/
provider.rs

1//! [`LineProvider`] trait for localisation / text substitution.
2
3/// Supplies localised (or otherwise substituted) text for a line.
4///
5/// When a line carries a `#line:<id>` tag, the runner queries the provider with that id.
6/// If the provider returns `Some(text)`, that replaces the original line text in the event.
7/// If it returns `None`, the original source text is used as-is.
8pub trait LineProvider: Send + Sync + 'static {
9    /// Returns localised text for `line_id`, or `None` to use the source text.
10    fn get(&self, line_id: &str) -> Option<String>;
11}
12
13/// A no-op provider that always returns `None` (source text is used unchanged).
14#[derive(Debug, Clone, Default)]
15pub struct PassthroughProvider;
16
17impl LineProvider for PassthroughProvider {
18    fn get(&self, _line_id: &str) -> Option<String> {
19        None
20    }
21}
22
23/// A simple in-memory provider backed by a [`std::collections::HashMap`].
24#[derive(Debug, Clone, Default)]
25pub struct HashMapProvider {
26    map: std::collections::HashMap<String, String>,
27}
28
29impl HashMapProvider {
30    /// Creates an empty provider.
31    #[must_use]
32    pub fn new() -> Self {
33        Self::default()
34    }
35
36    /// Inserts a localised string for the given id.
37    pub fn insert(&mut self, id: impl Into<String>, text: impl Into<String>) {
38        self.map.insert(id.into(), text.into());
39    }
40}
41
42impl LineProvider for HashMapProvider {
43    fn get(&self, line_id: &str) -> Option<String> {
44        self.map.get(line_id).cloned()
45    }
46}