portal_jsc_mob_backend_common/
lib.rs1#![no_std]
2
3use core::fmt::Display;
4
5use alloc::{
6 collections::btree_map::BTreeMap,
7 string::{String, ToString},
8 sync::Arc,
9 vec::{self, Vec},
10};
11extern crate alloc;
13
14#[derive(Clone)]
15pub struct Term<K> {
16 pub blocks: Vec<K>,
17 pub term: Arc<dyn Fn(&[String]) -> String>,
18}
19impl<K> Term<K> {
20 pub fn raw(a: String) -> Self {
21 Self {
22 blocks: alloc::vec![],
23 term: Arc::new(move |_| a.clone()),
24 }
25 }
26 pub fn core(k: K) -> Self {
27 Self {
28 blocks: alloc::vec![k],
29 term: Arc::new(|a| a[0].clone()),
30 }
31 }
32 pub fn prepend_stmt(self, a: String) -> Self {
33 let Self { blocks, term } = self;
34 Self {
35 blocks,
36 term: Arc::new(move |s| {
37 let t = term(s);
38 alloc::format!("{a};{t}")
39 }),
40 }
41 }
42 pub fn r#if(self, cond: String, r#else: Term<K>) -> Self {
43 let a = self.blocks.len();
44 let b = self.term.clone();
45 let c = r#else.term;
46 Self {
47 blocks: self
48 .blocks
49 .into_iter()
50 .chain(r#else.blocks.into_iter())
51 .collect(),
52 term: Arc::new(move |s| {
53 let (a, d) = s.split_at(a);
54 let b = b(a);
55 let c = c(a);
56 alloc::format!("if({cond}){{{b}}}else{{{c}}}")
57 }),
58 }
59 }
60 pub fn map<U, E>(self, f: &mut (dyn FnMut(K) -> Result<U, E> + '_)) -> Result<Term<U>, E> {
61 Ok(Term {
62 blocks: self.blocks.into_iter().map(f).collect::<Result<_, E>>()?,
63 term: self.term,
64 })
65 }
66 pub fn as_ref(&self) -> Term<&K> {
67 Term {
68 blocks: self.blocks.iter().collect(),
69 term: self.term.clone(),
70 }
71 }
72 pub fn as_mut(&mut self) -> Term<&mut K> {
73 Term {
74 blocks: self.blocks.iter_mut().collect(),
75 term: self.term.clone(),
76 }
77 }
78}
79impl<K: Display> Display for Term<K> {
80 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 write!(
82 f,
83 "{}",
84 (self.term)(
85 &self
86 .blocks
87 .iter()
88 .map(|a| a.to_string())
89 .collect::<Vec<_>>()
90 )
91 )
92 }
93}