Skip to content

Commit a2591bb

Browse files
committed
Idiomatic rust
1 parent dfbf4bc commit a2591bb

File tree

7 files changed

+124
-97
lines changed

7 files changed

+124
-97
lines changed

src/contract.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
1-
use std::path::PathBuf;
1+
use std::{path::Path, str::FromStr};
22

3-
use crate::{FieldList, Transition};
3+
use crate::{run_scilla_fmt, Error, FieldList, TransitionList};
44

55
#[derive(Debug, PartialEq)]
66
pub struct Contract {
7-
pub path: PathBuf,
87
pub name: String,
98
pub init_params: FieldList,
109
pub fields: FieldList,
11-
pub transitions: Vec<Transition>,
10+
pub transitions: TransitionList,
11+
}
12+
13+
impl FromStr for Contract {
14+
type Err = Error;
15+
16+
fn from_str(sexp: &str) -> Result<Self, Self::Err> {
17+
let v = lexpr::from_str(sexp)?;
18+
let name = v["contr"][0]["cname"]["Ident"][0][1].to_string();
19+
let transitions = (&v["contr"][0]["ccomps"][0]).try_into()?;
20+
let init_params = (&v["contr"][0]["cparams"][0]).try_into()?;
21+
let fields = (&v["contr"][0]["cfields"][0]).try_into()?;
22+
Ok(Contract {
23+
name,
24+
transitions,
25+
init_params,
26+
fields,
27+
})
28+
}
29+
}
30+
31+
impl Contract {
32+
pub fn from_path(contract_path: &Path) -> Result<Self, Error> {
33+
run_scilla_fmt(contract_path)?.replace("\\0", "").parse()
34+
}
1235
}

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ pub enum Error {
77
#[error("The requested entry {0} does not exist in the given S-expression")]
88
NoSuchEntryInSexp(String),
99

10+
#[error("Comptype is not transition. It's {0}")]
11+
CompTypeIsNotTransition(String),
12+
1013
#[error(transparent)]
1114
IoError(#[from] std::io::Error),
1215

src/field.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,21 @@ impl std::ops::Deref for FieldList {
4747
&self.0
4848
}
4949
}
50+
51+
impl TryFrom<&Value> for FieldList {
52+
type Error = Error;
53+
54+
fn try_from(value: &Value) -> Result<Self, Self::Error> {
55+
if !value.is_list() {
56+
return Ok(FieldList::default());
57+
}
58+
59+
let fields: Result<Vec<Field>, Error> = value
60+
.list_iter()
61+
.unwrap()
62+
.map(|elem| elem.try_into())
63+
.collect();
64+
65+
Ok(FieldList(fields?))
66+
}
67+
}

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
pub mod contract;
22
pub mod error;
33
pub mod field;
4-
pub mod parser;
54
pub mod transition;
65
pub mod r#type;
76

87
pub use contract::*;
98
pub use error::Error;
109
pub use field::*;
11-
pub use parser::*;
1210
pub use r#type::*;
1311
pub use transition::*;
1412

src/parser.rs

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/transition.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::FieldList;
1+
use lexpr::Value;
2+
3+
use crate::{Error, FieldList};
24

35
#[derive(Debug, PartialEq)]
46
pub struct Transition {
@@ -21,3 +23,49 @@ impl Transition {
2123
}
2224
}
2325
}
26+
27+
impl TryFrom<&Value> for Transition {
28+
type Error = Error;
29+
30+
fn try_from(value: &Value) -> Result<Self, Self::Error> {
31+
let comp_type = value["comp_type"][0].as_symbol().unwrap();
32+
if comp_type == "CompTrans" {
33+
let transition_name = value["comp_name"][0]["SimpleLocal"][0].to_string();
34+
Ok(Transition {
35+
name: transition_name,
36+
params: (&value["comp_params"][0]).try_into()?,
37+
})
38+
} else {
39+
Err(Error::CompTypeIsNotTransition(comp_type.to_string()))
40+
}
41+
}
42+
}
43+
44+
#[derive(Debug, PartialEq, Default)]
45+
pub struct TransitionList(pub Vec<Transition>);
46+
47+
impl std::ops::Deref for TransitionList {
48+
type Target = Vec<Transition>;
49+
50+
fn deref(&self) -> &Self::Target {
51+
&self.0
52+
}
53+
}
54+
55+
impl TryFrom<&Value> for TransitionList {
56+
type Error = Error;
57+
58+
fn try_from(value: &Value) -> Result<Self, Self::Error> {
59+
if !value.is_list() {
60+
return Ok(TransitionList::default());
61+
}
62+
63+
Ok(TransitionList(
64+
value
65+
.list_iter()
66+
.unwrap()
67+
.filter_map(|elem| Transition::try_from(elem).ok())
68+
.collect(),
69+
))
70+
}
71+
}

0 commit comments

Comments
 (0)