1#[cfg(feature = "pint-abi-gen")]
7#[doc(inline)]
8pub use pint_abi_gen::from_file as gen_from_file;
9#[cfg(feature = "pint-abi-gen")]
10#[doc(inline)]
11pub use pint_abi_gen::from_str as gen_from_str;
12
13#[doc(inline)]
14pub use decode::Decode;
15#[doc(inline)]
16pub use encode::Encode;
17#[doc(inline)]
18pub use read::Read;
19#[doc(inline)]
20pub use write::Write;
21
22use std::{collections::BTreeSet, path::Path};
23use thiserror::Error;
24use types::{
25 essential::{
26 contract::Contract,
27 predicate::{Predicate, Program},
28 Word,
29 },
30 ContractABI, PredicateABI,
31};
32
33pub mod decode;
34mod encode;
35pub mod key;
36mod read;
37mod write;
38
39pub mod types {
41 #[doc(inline)]
44 pub use pint_abi_types::*;
45 #[doc(inline)]
47 pub use essential_types as essential;
48}
49
50#[derive(Debug, Error)]
52pub enum FromPathError {
53 #[error("an I/O error occurred: {0}")]
55 Io(#[from] std::io::Error),
56 #[error("failed to deserialize the ABI from JSON: {0}")]
58 Json(#[from] serde_json::Error),
59}
60
61#[derive(Debug, Error)]
64#[error("invalid slice length: `{remaining}` words too many")]
65pub struct TooManyWords {
66 pub remaining: usize,
68}
69
70#[derive(Debug, Error)]
72pub enum DecodeError<E> {
73 #[error("{0}")]
75 Decode(E),
76 #[error("{0}")]
78 TooManyWords(#[from] TooManyWords),
79}
80
81pub fn encode<T: Encode>(t: &T) -> Vec<Word> {
83 let mut v = vec![];
84 t.encode(&mut v)
85 .expect("encoding into `Vec<Word>` cannot error");
86 v
87}
88
89pub fn decode<T: Decode>(mut words: &[Word]) -> Result<T, DecodeError<T::Error>> {
94 let cursor = &mut words;
95 let t = T::decode(cursor).map_err(DecodeError::Decode)?;
96 if !cursor.is_empty() {
97 let remaining = cursor.len();
98 return Err(TooManyWords { remaining }.into());
99 }
100 Ok(t)
101}
102
103pub fn from_path(path: &Path) -> Result<ContractABI, FromPathError> {
108 let json_str = std::fs::read_to_string(path)?;
109 let abi = serde_json::from_str(&json_str)?;
110 Ok(abi)
111}
112
113pub fn contract_from_path(path: &Path) -> Result<(Contract, BTreeSet<Program>), FromPathError> {
118 let json_str = std::fs::read_to_string(path)?;
119 let abi = serde_json::from_str(&json_str)?;
120 Ok(abi)
121}
122
123pub fn find_predicate<'a>(
128 contract: &'a Contract,
129 abi: &'a ContractABI,
130 pred_name: &str,
131) -> Option<(&'a Predicate, &'a PredicateABI)> {
132 const ROOT_NAME: &str = "";
138 let skip_root_predicate = abi.predicates.len() > 1
139 && matches!(abi.predicates.first(), Some(p) if p.name == ROOT_NAME);
140
141 let mut abi_predicates = abi.predicates.iter();
143 if skip_root_predicate {
144 abi_predicates.next();
145 }
146
147 contract
149 .predicates
150 .iter()
151 .zip(abi_predicates)
152 .find(|(_, pred_abi)| predicate_name_matches(&pred_abi.name, pred_name))
153}
154
155fn predicate_name_matches(abi_pred_name: &str, pred_name: &str) -> bool {
158 abi_pred_name == pred_name || abi_pred_name.split("::").nth(1) == Some(pred_name)
159}