scilla_parser/contract.rs
1use std::{path::Path, str::FromStr};
2
3use crate::{
4 parser::{lexer::Lexer, parser},
5 simplified_representation::emitter::SrEmitter,
6 Error, FieldList, TransitionList,
7};
8
9#[derive(Debug, PartialEq, Default)]
10/// The `Contract` struct represents a parsed contract in Rust, including its name, initialization
11/// parameters, fields, and transitions.
12pub struct Contract {
13 /// Name of the parsed contract
14 pub name: String,
15 /// List of parameters needed to deploy the contract.
16 pub init_params: FieldList,
17 /// List of the contract's fields.
18 pub fields: FieldList,
19 /// List of the contract's transitions.
20 pub transitions: TransitionList,
21}
22
23impl FromStr for Contract {
24 type Err = Error;
25
26 /// Parse a Contract from a string slice
27 /// # Example
28 /// ```
29 /// use std::{error::Error, path::PathBuf};
30 /// use scilla_parser::{Contract, Field, FieldList, Transition, TransitionList, Type};
31 /// let contract_path = PathBuf::from("tests/contracts/chainid.scilla");
32 /// let contract_str = include_str!("../tests/contracts/chainid.scilla");
33 /// let contract = contract_str.parse::<Contract>().unwrap();
34 ///
35 /// assert_eq!(
36 /// contract,
37 /// Contract {
38 /// name: "ChainId".to_string(),
39 /// fields: FieldList(vec![Field::new("dummy_field", Type::Uint256)]),
40 /// init_params: FieldList::default(),
41 /// transitions: TransitionList(vec![Transition::new(
42 /// "EventChainID",
43 /// FieldList::default()
44 /// )])
45 /// }
46 /// );
47 /// ```
48 fn from_str(contract: &str) -> Result<Self, Self::Err> {
49 let mut errors = vec![];
50 let parsed = parser::ProgramParser::new().parse(&mut errors, Lexer::new(contract))?;
51
52 let emitter = SrEmitter::default();
53 emitter.emit(&parsed).map_err(Error::ParseError)
54 }
55}
56
57impl Contract {
58 /// Parse a contract from a given path.
59 ///
60 /// # Examples
61 ///
62 /// ```
63 /// use std::{error::Error, path::PathBuf};
64 /// use scilla_parser::{Contract, Field, FieldList, Transition, TransitionList, Type};
65 /// let contract_path = PathBuf::from("tests/contracts/chainid.scilla");
66 /// let contract = Contract::parse(&contract_path).unwrap();
67 ///
68 /// assert_eq!(
69 /// contract,
70 /// Contract {
71 /// name: "ChainId".to_string(),
72 /// fields: FieldList(vec![Field::new("dummy_field", Type::Uint256)]),
73 /// init_params: FieldList::default(),
74 /// transitions: TransitionList(vec![Transition::new(
75 /// "EventChainID",
76 /// FieldList::default()
77 /// )])
78 /// }
79 /// );
80 /// ```
81 pub fn parse(contract_path: &Path) -> Result<Self, Error> {
82 std::fs::read_to_string(contract_path)?.parse()
83 }
84}