ptero/method/
trailing_unicode.rs1pub mod character_sets;
14
15use std::error::Error;
16
17use crate::{
18 binary::BitVec,
19 context::{Context, ContextError},
20 decoder::Decoder,
21 encoder::{Capacity, Encoder, EncoderResult},
22};
23use log::trace;
24
25use crate::binary::Bit;
26
27use self::character_sets::{CharacterSetType, GetCharacterSet};
28
29use super::Method;
30
31#[derive(Debug, PartialEq)]
37pub struct TrailingUnicodeMethod {
38 character_set: CharacterSetType,
39}
40
41impl Default for TrailingUnicodeMethod {
42 fn default() -> Self {
43 Self::new(CharacterSetType::FullUnicodeSet)
44 }
45}
46
47impl TrailingUnicodeMethod {
48 pub fn new(unicode_set: CharacterSetType) -> Self {
49 TrailingUnicodeMethod {
50 character_set: unicode_set,
51 }
52 }
53}
54
55impl Capacity for TrailingUnicodeMethod {
56 fn bitrate(&self) -> usize {
57 let amount_of_bits = std::mem::size_of::<usize>() * 8;
58 amount_of_bits - self.character_set.size().leading_zeros() as usize
59 }
60}
61
62impl<E> Encoder<E> for TrailingUnicodeMethod
63where
64 E: Context,
65{
66 fn partial_encode(
67 &self,
68 context: &mut E,
69 data: &mut dyn Iterator<Item = Bit>,
70 ) -> Result<EncoderResult, Box<dyn Error>> {
71 let set_capacity = self.bitrate();
72 let next_n_bits = data.take(set_capacity).collect::<Vec<Bit>>();
73 let amount_bits_taken = next_n_bits.len();
75 let mut number: u32 = BitVec::from(next_n_bits).into();
76 number <<= set_capacity - amount_bits_taken;
77
78 trace!(
79 "Took {} bits and assembled a number: {}",
80 set_capacity,
81 number
82 );
83 if let Some(character) = self.character_set.get_character(number) {
84 trace!(
85 "Putting unicode character {:?} at the end of the line",
86 character
87 );
88 context.get_current_text_mut()?.push(*character);
89 }
90
91 Ok(EncoderResult::Success)
92 }
93}
94
95impl<D> Decoder<D> for TrailingUnicodeMethod
96where
97 D: Context,
98{
99 fn partial_decode(&self, context: &D) -> Result<Vec<Bit>, ContextError> {
100 if let Some(character) = context.get_current_text()?.chars().last() {
101 let decoded_number = self.character_set.character_to_bits(&character);
102 trace!(
103 "Found {:?} at the end of the line, decoded into {}",
104 &character,
105 decoded_number
106 );
107 let data: Vec<Bit> = BitVec::from(decoded_number).into();
108 let data_length = data.len();
109 let data_iter = data.into_iter().skip(data_length - self.bitrate());
111 let decoded_data = data_iter.collect::<Vec<Bit>>();
112 return Ok(decoded_data);
113 }
114
115 Ok(BitVec::filled_with(0, self.bitrate()).into())
116 }
117}
118
119impl<E, D> Method<E, D> for TrailingUnicodeMethod
120where
121 E: Context,
122 D: Context,
123{
124 fn method_name(&self) -> String {
125 "TrailingUnicodeMethod".to_string()
126 }
127}