poa-bridge/bridge/src/database.rs

92 lines
2.6 KiB
Rust
Raw Normal View History

2017-06-25 04:21:13 -07:00
use std::path::Path;
2017-08-04 08:57:09 -07:00
use std::{io, str, fs, fmt};
2017-06-25 04:21:13 -07:00
use std::io::{Read, Write};
2017-08-04 08:57:09 -07:00
use web3::types::Address;
2017-06-25 04:21:13 -07:00
use toml;
2017-08-04 08:57:09 -07:00
use error::{Error, ResultExt, ErrorKind};
2017-06-25 04:21:13 -07:00
/// Application "database".
2017-08-28 07:48:01 -07:00
#[derive(Debug, PartialEq, Deserialize, Serialize, Default, Clone)]
2017-08-01 02:36:48 -07:00
pub struct Database {
2017-10-10 02:02:46 -07:00
/// Address of home contract.
pub home_contract_address: Address,
/// Address of foreign contract.
pub foreign_contract_address: Address,
/// Number of block at which home contract has been deployed.
pub home_deploy: Option<u64>,
2017-10-10 02:02:46 -07:00
/// Number of block at which foreign contract has been deployed.
pub foreign_deploy: Option<u64>,
2017-08-13 03:21:51 -07:00
/// Number of last block which has been checked for deposit relays.
pub checked_deposit_relay: u64,
/// Number of last block which has been checked for withdraw relays.
pub checked_withdraw_relay: u64,
/// Number of last block which has been checked for withdraw confirms.
pub checked_withdraw_confirm: u64,
2017-06-25 04:21:13 -07:00
}
2017-08-04 08:57:09 -07:00
impl str::FromStr for Database {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
toml::from_str(s).chain_err(|| "Cannot parse database")
}
}
impl fmt::Display for Database {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&toml::to_string(self).expect("serialization can't fail; qed"))
}
}
2017-08-01 02:36:48 -07:00
impl Database {
2017-08-02 03:45:15 -07:00
pub fn load<P: AsRef<Path>>(path: P) -> Result<Database, Error> {
2017-08-04 08:57:09 -07:00
let mut file = match fs::File::open(&path) {
Ok(file) => file,
Err(ref err) if err.kind() == io::ErrorKind::NotFound => return Err(ErrorKind::MissingFile(format!("{:?}", path.as_ref())).into()),
Err(err) => return Err(err).chain_err(|| "Cannot open database"),
};
2017-06-25 04:21:13 -07:00
let mut buffer = String::new();
2017-08-28 07:48:01 -07:00
file.read_to_string(&mut buffer)?;
2017-08-04 08:57:09 -07:00
buffer.parse()
2017-06-25 04:21:13 -07:00
}
2017-08-28 07:48:01 -07:00
pub fn save<W: Write>(&self, mut write: W) -> Result<(), Error> {
write.write_all(self.to_string().as_bytes())?;
2017-06-25 04:21:13 -07:00
Ok(())
}
}
#[cfg(test)]
mod tests {
2017-08-13 03:21:51 -07:00
use super::Database;
2017-06-25 04:21:13 -07:00
#[test]
2017-09-28 15:59:19 -07:00
fn database_to_and_from_str() {
2017-08-25 02:58:47 -07:00
let toml =
2017-10-10 02:02:46 -07:00
r#"home_contract_address = "0x49edf201c1e139282643d5e7c6fb0c7219ad1db7"
foreign_contract_address = "0x49edf201c1e139282643d5e7c6fb0c7219ad1db8"
home_deploy = 100
foreign_deploy = 101
2017-08-13 03:21:51 -07:00
checked_deposit_relay = 120
checked_withdraw_relay = 121
checked_withdraw_confirm = 121
2017-06-25 04:21:13 -07:00
"#;
2017-08-01 02:36:48 -07:00
let expected = Database {
home_contract_address: "49edf201c1e139282643d5e7c6fb0c7219ad1db7".into(),
foreign_contract_address: "49edf201c1e139282643d5e7c6fb0c7219ad1db8".into(),
home_deploy: Some(100),
foreign_deploy: Some(101),
2017-08-13 03:21:51 -07:00
checked_deposit_relay: 120,
checked_withdraw_relay: 121,
checked_withdraw_confirm: 121,
2017-06-25 04:21:13 -07:00
};
2017-08-04 08:57:09 -07:00
let database = toml.parse().unwrap();
2017-06-25 04:21:13 -07:00
assert_eq!(expected, database);
2017-08-13 03:21:51 -07:00
let s = database.to_string();
assert_eq!(s, toml);
2017-06-25 04:21:13 -07:00
}
}