use crate::{Bip39Mnemonic, LegacySeed};
use anyhow::{Context, Result, bail};
use bc_envelope::prelude::*;
#[derive(Clone, PartialEq)]
pub enum SeedMaterial {
Bip39Mnemonic(Bip39Mnemonic),
LegacySeed(LegacySeed),
}
impl std::fmt::Debug for SeedMaterial {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Bip39Mnemonic(phrase) => {
write!(f, "SeedMaterial::Bip39Mnemonic(\"{:?}\")", phrase)
}
Self::LegacySeed(seed) => write!(f, "SeedMaterial::LegacySeed({:?})", seed),
}
}
}
impl std::fmt::Display for SeedMaterial {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Bip39Mnemonic(phrase) => {
write!(f, "SeedMaterial::Bip39Mnemonic(\"{:?}\")", phrase)
}
Self::LegacySeed(seed) => write!(f, "SeedMaterial::LegacySeed({:?})", seed),
}
}
}
impl From<SeedMaterial> for Envelope {
fn from(value: SeedMaterial) -> Self {
match value {
SeedMaterial::Bip39Mnemonic(mnemonic) => Envelope::new(mnemonic),
SeedMaterial::LegacySeed(seed) => Envelope::new(seed),
}
.add_type("SeedMaterial")
}
}
impl TryFrom<Envelope> for SeedMaterial {
type Error = anyhow::Error;
fn try_from(envelope: Envelope) -> Result<Self, Self::Error> {
envelope
.check_type_envelope("SeedMaterial")
.context("SeedMaterial")?;
if let Ok(mnemonic) = Bip39Mnemonic::try_from(envelope.clone()) {
Ok(SeedMaterial::Bip39Mnemonic(mnemonic))
} else if let Ok(seed) = LegacySeed::try_from(envelope.clone()) {
Ok(SeedMaterial::LegacySeed(seed))
} else {
bail!("Invalid SeedMaterial envelope")
}
}
}
#[cfg(test)]
mod tests {
use crate::{Bip39Mnemonic, LegacySeed, test_envelope_roundtrip};
use super::SeedMaterial;
impl crate::RandomInstance for SeedMaterial {
fn random() -> Self {
if rand::random::<bool>() {
SeedMaterial::Bip39Mnemonic(Bip39Mnemonic::random())
} else {
SeedMaterial::LegacySeed(LegacySeed::random())
}
}
}
test_envelope_roundtrip!(SeedMaterial, 10, true);
}