Skip to main content

link_cli/sequences/
unicode_sequence_to_string_converter.rs

1use anyhow::{bail, Result};
2
3use crate::link_storage::LinkStorage;
4use crate::sequences::{RightSequenceWalker, TargetMatcher, UnicodeSymbolToCharConverter};
5
6#[derive(Clone, Copy, Debug)]
7pub struct UnicodeSequenceToStringConverter {
8    unicode_sequence_criterion_matcher: TargetMatcher,
9    sequence_walker: RightSequenceWalker,
10    unicode_symbol_to_char_converter: UnicodeSymbolToCharConverter,
11    unicode_sequence_type: u32,
12}
13
14impl UnicodeSequenceToStringConverter {
15    pub fn new(
16        unicode_sequence_criterion_matcher: TargetMatcher,
17        sequence_walker: RightSequenceWalker,
18        unicode_symbol_to_char_converter: UnicodeSymbolToCharConverter,
19        unicode_sequence_type: u32,
20    ) -> Self {
21        Self {
22            unicode_sequence_criterion_matcher,
23            sequence_walker,
24            unicode_symbol_to_char_converter,
25            unicode_sequence_type,
26        }
27    }
28
29    pub fn convert(&self, links: &LinkStorage, sequence: u32) -> Result<String> {
30        if sequence == self.unicode_sequence_type {
31            return Ok(String::new());
32        }
33        if !self
34            .unicode_sequence_criterion_matcher
35            .is_matched(links, sequence)
36        {
37            bail!("Specified link {sequence} is not a Unicode sequence.");
38        }
39
40        let Some(sequence_link) = links.get(sequence) else {
41            bail!("Unicode sequence link {sequence} does not exist.");
42        };
43        let code_units = self
44            .sequence_walker
45            .walk(links, sequence_link.source)
46            .into_iter()
47            .map(|symbol| self.unicode_symbol_to_char_converter.convert(links, symbol))
48            .collect::<Result<Vec<_>>>()?;
49
50        Ok(String::from_utf16(&code_units)?)
51    }
52}