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 pub fn add(self, s: &str) -> Translatable {
43 Translatable {
44 code: self.code + s,
45 ..self
46 }
47 }
48
49 pub fn append(self, val: impl TranslateAppendable) -> Translatable {
50 self + val.to_translatable()
51 }
52
53 pub fn append_safe(self, val: impl TranslateAppendable) -> Translatable {
54 self + val.to_translatable().reset_context()
55 }
56
57 pub fn get_code(&self) -> String {
58 self.code.clone()
59 }
60
61 pub fn join(self, vals: &[Lang], joint: &str) -> Translatable {
62 if vals.len() > 0 {
63 vals.into_iter()
64 .fold(self, |trans, val| trans.to_r(val).add(joint))
65 .sub(joint.len())
66 } else {
67 self
68 }
69 }
70
71 pub fn join_arg_val(self, vals: &[ArgumentValue], joint: &str) -> Translatable {
72 vals.into_iter()
73 .fold(self, |trans, val| trans.to_r_arg_val(val, joint))
74 .sub(joint.len())
75 }
76
77 pub fn sub(self, len: usize) -> Translatable {
78 let new_code = if self.code.len() > len {
79 &self.code[0..(self.code.len() - len)]
80 } else {
81 &self.code
82 };
83 Translatable {
84 code: new_code.to_string(),
85 ..self
86 }
87 }
88}
89
90impl Add for Translatable {
91 type Output = Translatable;
92
93 fn add(self, other: Self) -> Self::Output {
94 let new_context = (other.context == Context::default())
95 .then_some(self.context)
96 .unwrap_or(other.context);
97 Translatable {
98 context: new_context,
99 code: self.code + &other.code,
100 }
101 }
102}
103
104impl From<Context> for Translatable {
105 fn from(val: Context) -> Self {
106 Translatable {
107 context: val,
108 code: "".to_string(),
109 }
110 }
111}
112
113impl From<Translatable> for (String, Context) {
114 fn from(val: Translatable) -> Self {
115 (val.code, val.context)
116 }
117}
118
119impl TranslateAppendable for (String, Context) {
120 fn to_translatable(self) -> Translatable {
121 Translatable {
122 context: self.1,
123 code: self.0,
124 }
125 }
126}
127
128impl TranslateAppendable for String {
129 fn to_translatable(self) -> Translatable {
130 Translatable {
131 context: Context::default(),
132 code: self,
133 }
134 }
135}
136
137impl RTranslatable<(String, Context)> for Box<Lang> {
138 fn to_r(&self, context: &Context) -> (String, Context) {
139 (**self).to_r(context)
140 }
141}