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}