subweight_core/parse/
overhead.rs1use syn::ItemConst;
2
3use crate::{
4 parse::path_to_string,
5 term::{ChromaticTerm, SimpleTerm},
6 *,
7};
8
9#[derive(Debug, PartialEq, Eq, Clone)]
10pub enum Weight {
11 BlockExecution(ChromaticTerm),
12 ExtrinsicBase(ChromaticTerm),
13}
14
15pub fn parse_file(file: &Path) -> Result<Weight, String> {
16 let content = super::read_file(file)?;
17 parse_content(content)
18}
19
20pub fn parse_content(content: String) -> Result<Weight, String> {
21 let ast = syn::parse_file(&content).map_err(|e| e.to_string())?;
22 for item in ast.items {
23 if let Ok(res) = handle_item(&item) {
24 return Ok(res)
25 }
26 }
27 Err("No Overhead weights found".to_string())
28}
29
30fn handle_item(item: &Item) -> Result<Weight, String> {
31 match item {
32 Item::Mod(m) => {
34 if m.ident == "constants" {
35 if let Some((_, content)) = m.content.as_ref() {
36 for item in content {
37 let res = handle_item(item);
38 if res.is_ok() {
40 return res
41 }
42 }
43 return Err("Did not find parameter_types!".into())
44 }
45 }
46 Err(format!("Unexpected module: {}", m.ident))
47 },
48 Item::Macro(m) => {
49 let name = m.mac.path.segments.last();
50 if name.unwrap().ident == "parameter_types" {
51 parse_macro(m.mac.tokens.clone())
52 } else {
53 Err("Unexpected macro def".into())
54 }
55 },
56 _ => Err("Could not find overhead weight in the file".into()),
57 }
58}
59
60fn parse_macro(tokens: proc_macro2::TokenStream) -> Result<Weight, String> {
67 let def: ItemConst = syn::parse2(tokens).map_err(|e| e.to_string())?;
68 let name = def.ident.to_string();
69
70 let type_name = type_to_string(&def.ty, None)?;
71 if type_name != "Weight" {
72 return Err(format!("Unexpected const type: {}", type_name))
73 }
74 let weight: ChromaticTerm = match def.expr.as_ref() {
75 Expr::Binary(bin) => {
76 let simple: SimpleTerm = bin.try_into()?;
77 Ok(simple.into_chromatic(crate::Dimension::Time))
78 },
79 e => super::pallet::parse_expression(e),
80 }?;
81
82 match name.as_str() {
83 "BlockExecutionWeight" => Ok(Weight::BlockExecution(weight)),
84 "ExtrinsicBaseWeight" => Ok(Weight::ExtrinsicBase(weight)),
85 _ => Err(format!("Unexpected const name: {}", name)),
86 }
87}
88
89fn type_to_string(p: &syn::Type, delimiter: Option<&str>) -> Result<String, String> {
91 if let Type::Path(p) = p {
92 Ok(path_to_string(&p.path, delimiter))
93 } else {
94 Err("Unexpected type".into())
95 }
96}