Skip to main content

typr_core/processes/transpiling/
translatable.rs

1use 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}