1use crate::{
4 term::{ChromaticTerm, SimpleTerm},
5 WEIGHT_PER_NANOS,
6};
7use core::fmt::Display;
8use serde::{Deserialize, Serialize};
9use std::collections::BTreeMap as Map;
10
11pub const STORAGE_READ_VAR: &str = "READ";
12pub const STORAGE_WRITE_VAR: &str = "WRITE";
13
14#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, PartialOrd, Ord, Eq)]
15#[cfg_attr(feature = "bloat", derive(Default))]
16pub struct Scope<T> {
17 vars: Map<String, T>,
18}
19
20pub type SimpleScope = Scope<SimpleTerm>;
21pub type ChromaticScope = Scope<ChromaticTerm>;
22
23impl SimpleScope {
24 pub fn from_substrate() -> Self {
25 (Self { vars: Map::default() })
26 .with_var("WEIGHT_PER_NANOS", SimpleTerm::Scalar(WEIGHT_PER_NANOS))
27 .with_var("WEIGHT_REF_TIME_PER_NANOS", SimpleTerm::Scalar(WEIGHT_PER_NANOS))
28 .with_var("constants::WEIGHT_PER_NANOS", SimpleTerm::Scalar(WEIGHT_PER_NANOS))
29 .with_var("constants::WEIGHT_REF_TIME_PER_NANOS", SimpleTerm::Scalar(WEIGHT_PER_NANOS))
30 }
31
32 pub fn with_storage_weights(self, read: SimpleTerm, write: SimpleTerm) -> Self {
33 self.with_var(STORAGE_READ_VAR, read).with_var(STORAGE_WRITE_VAR, write)
34 }
35}
36
37impl<T> Scope<T>
38where
39 T: Clone,
40{
41 pub fn empty() -> Self {
42 Self { vars: Map::default() }
43 }
44
45 pub fn put_var(&mut self, name: &str, value: T) {
46 self.vars.insert(name.into(), value);
47 }
48
49 pub fn with_var(&self, name: &str, value: T) -> Self {
50 let mut ret = self.clone();
51 ret.vars.insert(name.into(), value);
52 ret
53 }
54
55 pub fn get(&self, name: &str) -> Option<T> {
56 self.vars.get(name).cloned()
57 }
58
59 pub fn merge(self, other: Self) -> Self {
60 Self { vars: self.vars.into_iter().chain(other.vars).collect() }
61 }
62
63 pub fn extend(&mut self, other: Self) {
64 self.vars.extend(other.vars);
65 }
66
67 pub fn len(&self) -> usize {
68 self.vars.len()
69 }
70
71 pub fn is_empty(&self) -> bool {
72 self.vars.is_empty()
73 }
74
75 pub fn as_vec(&self) -> Vec<(String, T)> {
76 self.vars.clone().into_iter().collect()
77 }
78}
79
80impl<T: Display> Display for Scope<T> {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 let s = self
83 .vars
84 .iter()
85 .map(|(k, v)| format!("{} = {}", k, v))
86 .collect::<Vec<_>>()
87 .join(", ");
88 write!(f, "{}", s)
89 }
90}