typr_core/processes/transpiling/
translatable.rs1use crate::components::context::Context;
2use crate::components::language::argument_value::ArgumentValue;
3use crate::components::language::Lang;
4use std::ops::Add;
5
6pub trait TranslateAppendable {
7 fn to_translatable(self) -> Translatable;
8}
9
10pub trait RTranslatable<T: TranslateAppendable> {
11 fn to_r(&self, context: &Context) -> T;
12}
13
14pub struct Translatable {
15 context: Context,
16 code: String,
17}
18
19impl Translatable {
20 pub fn to_r<T: TranslateAppendable>(self, lang: &impl RTranslatable<T>) -> Translatable {
21 let res = lang.to_r(&self.context);
22 self.append(res)
23 }
24
25 pub fn to_r_safe<T: TranslateAppendable>(self, lang: &impl RTranslatable<T>) -> Translatable {
26 let res = lang.to_r(&self.context);
27 self.append_safe(res)
28 }
29
30 pub fn reset_context(self) -> Translatable {
31 Translatable {
32 context: Context::default(),
33 ..self
34 }
35 }
36
37 pub fn to_r_arg_val(self, arg_val: &ArgumentValue, joint: &str) -> Translatable {
38 let res = arg_val.to_r(&self.context);
39 self.add(&res).add(joint)
40 }
41
42 #[allow(clippy::should_implement_trait)]
43 pub fn add(self, s: &str) -> Translatable {
44 Translatable {
45 code: self.code + s,
46 ..self
47 }
48 }
49
50 pub fn append(self, val: impl TranslateAppendable) -> Translatable {
51 self + val.to_translatable()
52 }
53
54 pub fn append_safe(self, val: impl TranslateAppendable) -> Translatable {
55 self + val.to_translatable().reset_context()
56 }
57
58 pub fn get_code(&self) -> String {
59 self.code.clone()
60 }
61
62 pub fn join(self, vals: &[Lang], joint: &str) -> Translatable {
63 if !vals.is_empty() {
64 vals.iter()
65 .fold(self, |trans, val| trans.to_r(val).add(joint))
66 .sub(joint.len())
67 } else {
68 self
69 }
70 }
71
72 pub fn join_arg_val(self, vals: &[ArgumentValue], joint: &str) -> Translatable {
73 vals.iter()
74 .fold(self, |trans, val| trans.to_r_arg_val(val, joint))
75 .sub(joint.len())
76 }
77
78 #[allow(clippy::should_implement_trait)]
79 pub fn sub(self, len: usize) -> Translatable {
80 let new_code = if self.code.len() > len {
81 &self.code[0..(self.code.len() - len)]
82 } else {
83 &self.code
84 };
85 Translatable {
86 code: new_code.to_string(),
87 ..self
88 }
89 }
90}
91
92impl Add for Translatable {
93 type Output = Translatable;
94
95 fn add(self, other: Self) -> Self::Output {
96 let new_context = if other.context == Context::default() {
97 self.context
98 } else {
99 other.context
100 };
101 Translatable {
102 context: new_context,
103 code: self.code + &other.code,
104 }
105 }
106}
107
108impl From<Context> for Translatable {
109 fn from(val: Context) -> Self {
110 Translatable {
111 context: val,
112 code: "".to_string(),
113 }
114 }
115}
116
117impl From<Translatable> for (String, Context) {
118 fn from(val: Translatable) -> Self {
119 (val.code, val.context)
120 }
121}
122
123impl TranslateAppendable for (String, Context) {
124 fn to_translatable(self) -> Translatable {
125 Translatable {
126 context: self.1,
127 code: self.0,
128 }
129 }
130}
131
132impl TranslateAppendable for String {
133 fn to_translatable(self) -> Translatable {
134 Translatable {
135 context: Context::default(),
136 code: self,
137 }
138 }
139}
140
141impl RTranslatable<(String, Context)> for Box<Lang> {
142 fn to_r(&self, context: &Context) -> (String, Context) {
143 (**self).to_r(context)
144 }
145}