link_cli/sequences/
unicode_sequence_to_string_converter.rs1use 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}