use crate::*;
impl FromPestPair for CertificationDocument {
fn from_pest_pair(cert_pair: Pair<Rule>) -> Result<Self, TextParseError> {
let cert_vx_pair = cert_pair
.into_inner()
.next()
.unwrap_or_else(|| unreachable!());
match cert_vx_pair.as_rule() {
Rule::cert_v10 => CertificationDocumentV10::from_pest_pair(cert_vx_pair)
.map(CertificationDocument::V10),
_ => Err(TextParseError::UnexpectedVersion(format!(
"{:#?}",
cert_vx_pair.as_rule()
))),
}
}
}
impl FromPestPair for CertificationDocumentV10 {
fn from_pest_pair(pair: Pair<Rule>) -> Result<CertificationDocumentV10, TextParseError> {
let mut currency = "";
let mut pubkeys = Vec::with_capacity(2);
let mut uid = "";
let mut sigs = Vec::with_capacity(2);
let mut blockstamps = Vec::with_capacity(2);
for field in pair.into_inner() {
match field.as_rule() {
Rule::currency => currency = field.as_str(),
Rule::pubkey => pubkeys.push(
ed25519::PublicKey::from_base58(field.as_str())
.unwrap_or_else(|_| unreachable!()), ),
Rule::uid => {
uid = field.as_str();
}
Rule::blockstamp => {
let mut inner_rules = field.into_inner();
let block_number: &str = inner_rules
.next()
.unwrap_or_else(|| unreachable!())
.as_str();
let block_hash: &str = inner_rules
.next()
.unwrap_or_else(|| unreachable!())
.as_str();
blockstamps.push(Blockstamp {
number: BlockNumber(
block_number.parse().unwrap_or_else(|_| unreachable!()),
), hash: BlockHash(
Hash::from_hex(block_hash).unwrap_or_else(|_| unreachable!()),
), });
}
Rule::ed25519_sig => {
sigs.push(
ed25519::Signature::from_base64(field.as_str())
.unwrap_or_else(|_| unreachable!()), );
}
Rule::EOI => (),
_ => panic!("unexpected rule"), }
}
Ok(CertificationDocumentV10Builder {
issuer: pubkeys[0],
currency,
target: pubkeys[1],
identity_username: uid,
identity_blockstamp: blockstamps[0],
identity_sig: sigs[0],
blockstamp: blockstamps[1],
}
.build_with_signature(svec![sigs[1]]))
}
}
#[cfg(test)]
mod tests {
use super::*;
use unwrap::unwrap;
#[test]
fn parse_certification_document() {
let doc = "Version: 10
Type: Certification
Currency: g1-test
Issuer: 5B8iMAzq1dNmFe3ZxFTBQkqhq4fsztg1gZvxHXCk1XYH
IdtyIssuer: mMPioknj2MQCX9KyKykdw8qMRxYR2w1u3UpdiEJHgXg
IdtyUniqueID: mmpio
IdtyTimestamp: 7543-000044410C5370DE8DBA911A358F318096B7A269CFC2BB93272E397CC513EA0A
IdtySignature: SmSweUD4lEMwiZfY8ux9maBjrQQDkC85oMNsin6oSQCPdXG8sFCZ4FisUaWqKsfOlZVb/HNa+TKzD2t0Yte+DA==
CertTimestamp: 167884-0001DFCA28002A8C96575E53B8CEF8317453A7B0BA255542CCF0EC8AB5E99038
wqZxPEGxLrHGv8VdEIfUGvUcf+tDdNTMXjLzVRCQ4UhlhDRahOMjfcbP7byNYr5OfIl83S1MBxF7VJgu8YasCA==";
let doc = unwrap!(CertificationDocument::parse_from_raw_text(doc));
println!("Doc : {:?}", doc);
assert!(doc.verify_signatures().is_ok());
assert_eq!(
doc.to_compact_document().as_compact_text(),
"5B8iMAzq1dNmFe3ZxFTBQkqhq4fsztg1gZvxHXCk1XYH:\
mMPioknj2MQCX9KyKykdw8qMRxYR2w1u3UpdiEJHgXg:167884:\
wqZxPEGxLrHGv8VdEIfUGvUcf+tDdNTMXjLzVRCQ4UhlhDRahOMjfcbP7byNYr5OfIl83S1MBxF7VJgu8YasCA=="
);
}
}