use crate::error::{unknown_variant, Error};
use crate::{
encrypt::AeadType, Algorithm, ArmorType, Cipher, Compression, Curve, FeatureType, Hash,
KeyUsage,
};
use std::str::FromStr;
fn unknown(kind: &'static str, value: &str) -> Error {
unknown_variant(kind, value)
}
impl std::fmt::Display for Algorithm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Algorithm {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_uppercase().as_str() {
"RSA" => Ok(Algorithm::Rsa),
"ELGAMAL" => Ok(Algorithm::ElGamal),
"DSA" => Ok(Algorithm::Dsa),
"ECDH" => Ok(Algorithm::Ecdh),
"ECDSA" => Ok(Algorithm::Ecdsa),
"EDDSA" => Ok(Algorithm::Eddsa),
"SM2" => Ok(Algorithm::Sm2),
_ => Err(unknown("algorithm", s)),
}
}
}
impl std::fmt::Display for Curve {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Curve {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"NIST P-256" => Ok(Curve::P256),
"NIST P-384" => Ok(Curve::P384),
"NIST P-521" => Ok(Curve::P521),
"Ed25519" => Ok(Curve::Ed25519),
"Curve25519" => Ok(Curve::Curve25519),
"brainpoolP256r1" => Ok(Curve::Bp256),
"brainpoolP384r1" => Ok(Curve::Bp384),
"brainpoolP512r1" => Ok(Curve::Bp512),
"secp256k1" => Ok(Curve::Secp256k1),
"SM2 P-256" => Ok(Curve::Sm2P256),
_ => Err(unknown("curve", s)),
}
}
}
impl std::fmt::Display for Hash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Hash {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_uppercase().as_str() {
"SHA1" => Ok(Hash::Sha1),
"SHA224" => Ok(Hash::Sha224),
"SHA256" => Ok(Hash::Sha256),
"SHA384" => Ok(Hash::Sha384),
"SHA512" => Ok(Hash::Sha512),
"SHA3-256" => Ok(Hash::Sha3_256),
"SHA3-512" => Ok(Hash::Sha3_512),
"MD5" => Ok(Hash::Md5),
"RIPEMD160" => Ok(Hash::Ripemd160),
"SM3" => Ok(Hash::Sm3),
_ => Err(unknown("hash", s)),
}
}
}
impl std::fmt::Display for Cipher {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Cipher {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_uppercase().as_str() {
"IDEA" => Ok(Cipher::Idea),
"TRIPLEDES" => Ok(Cipher::Tripledes),
"CAST5" => Ok(Cipher::Cast5),
"BLOWFISH" => Ok(Cipher::Blowfish),
"AES128" => Ok(Cipher::Aes128),
"AES192" => Ok(Cipher::Aes192),
"AES256" => Ok(Cipher::Aes256),
"TWOFISH" => Ok(Cipher::Twofish),
"CAMELLIA128" => Ok(Cipher::Camellia128),
"CAMELLIA192" => Ok(Cipher::Camellia192),
"CAMELLIA256" => Ok(Cipher::Camellia256),
"SM4" => Ok(Cipher::Sm4),
_ => Err(unknown("cipher", s)),
}
}
}
impl std::fmt::Display for Compression {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Compression {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_uppercase().as_str() {
"ZIP" => Ok(Compression::Zip),
"ZLIB" => Ok(Compression::Zlib),
"BZIP2" => Ok(Compression::Bzip2),
_ => Err(unknown("compression", s)),
}
}
}
impl std::fmt::Display for KeyUsage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for KeyUsage {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"certify" => Ok(KeyUsage::Certify),
"sign" => Ok(KeyUsage::Sign),
"encrypt" => Ok(KeyUsage::EncryptComms),
_ => Err(unknown("key usage", s)),
}
}
}
impl std::fmt::Display for AeadType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for AeadType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_uppercase().as_str() {
"OCB" => Ok(AeadType::Ocb),
"EAX" => Ok(AeadType::Eax),
"GCM" => Ok(AeadType::Gcm),
_ => Err(unknown("aead", s)),
}
}
}
impl std::fmt::Display for ArmorType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for ArmorType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"message" => Ok(ArmorType::Message),
"public key" => Ok(ArmorType::PublicKey),
"secret key" => Ok(ArmorType::SecretKey),
"signature" => Ok(ArmorType::Signature),
"cleartext signed message" => Ok(ArmorType::Cleartext),
_ => Err(unknown("armor type", s)),
}
}
}
impl std::fmt::Display for FeatureType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for FeatureType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let strip_nul = |b: &'static [u8]| -> &'static str {
let end = b.iter().position(|&x| x == 0).unwrap_or(b.len());
std::str::from_utf8(&b[..end]).expect("RNP_FEATURE_* is ASCII")
};
let symm = strip_nul(crate::ffi::RNP_FEATURE_SYMM_ALG);
let aead = strip_nul(crate::ffi::RNP_FEATURE_AEAD_ALG);
let prot = strip_nul(crate::ffi::RNP_FEATURE_PROT_MODE);
let pk = strip_nul(crate::ffi::RNP_FEATURE_PK_ALG);
let hash = strip_nul(crate::ffi::RNP_FEATURE_HASH_ALG);
let comp = strip_nul(crate::ffi::RNP_FEATURE_COMP_ALG);
let curve = strip_nul(crate::ffi::RNP_FEATURE_CURVE);
match s {
x if x == symm => Ok(FeatureType::SymmetricAlgorithm),
x if x == aead => Ok(FeatureType::AeadAlgorithm),
x if x == prot => Ok(FeatureType::ProtectionMode),
x if x == pk => Ok(FeatureType::PublicKeyAlgorithm),
x if x == hash => Ok(FeatureType::HashAlgorithm),
x if x == comp => Ok(FeatureType::CompressionAlgorithm),
x if x == curve => Ok(FeatureType::Curve),
_ => Err(unknown("feature type", s)),
}
}
}
impl std::fmt::Display for crate::context::KeyringFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for crate::context::KeyringFormat {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_uppercase().as_str() {
"GPG" => Ok(crate::context::KeyringFormat::Gpg),
"KBX" => Ok(crate::context::KeyringFormat::Kbx),
"G10" => Ok(crate::context::KeyringFormat::G10),
"JSON" => Ok(crate::context::KeyringFormat::Json),
_ => Err(unknown("keyring format", s)),
}
}
}
#[allow(dead_code)]
fn _silence() {}