use multi_codec::{Codec, Error};
use multi_trait::TryDecodeFrom;
#[test]
fn test_full_encode_decode_cycle() {
let original = Codec::Ed25519Pub;
let bytes: Vec<u8> = original.into();
assert!(!bytes.is_empty());
let (decoded, remaining) = Codec::try_decode_from(&bytes).unwrap();
assert_eq!(decoded, original);
assert!(remaining.is_empty());
assert_eq!(decoded.code(), original.code());
assert_eq!(decoded.as_str(), original.as_str());
}
#[test]
fn test_conversion_chain() {
let original_name = "sha2-256";
let codec1 = Codec::try_from(original_name).unwrap();
let code: u64 = codec1.into();
let codec2 = Codec::try_from(code).unwrap();
let final_name = codec2.as_str();
assert_eq!(final_name, original_name);
assert_eq!(codec1, codec2);
}
#[test]
fn test_codec_in_struct() {
#[derive(Debug, PartialEq)]
struct Message {
algorithm: Codec,
data: Vec<u8>,
}
let msg = Message {
algorithm: Codec::Sha2256,
data: vec![1, 2, 3, 4],
};
assert_eq!(msg.algorithm.code(), 0x12);
assert_eq!(msg.algorithm.as_str(), "sha2-256");
let msg2 = Message {
algorithm: msg.algorithm,
data: msg.data.clone(),
};
assert_eq!(msg, msg2);
}
#[test]
fn test_codec_as_hashmap_key() {
use std::collections::HashMap;
let mut map = HashMap::new();
map.insert(Codec::Sha2256, "SHA-256 hash");
map.insert(Codec::Ed25519Pub, "Ed25519 public key");
map.insert(Codec::Identity, "Identity");
assert_eq!(map.get(&Codec::Sha2256), Some(&"SHA-256 hash"));
assert_eq!(map.get(&Codec::Ed25519Pub), Some(&"Ed25519 public key"));
assert_eq!(map.get(&Codec::Identity), Some(&"Identity"));
assert_eq!(map.len(), 3);
}
#[test]
fn test_codec_in_btreemap() {
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
map.insert(Codec::Ed25519Pub, "Last");
map.insert(Codec::Identity, "First");
map.insert(Codec::Sha2256, "Middle");
let keys: Vec<_> = map.keys().copied().collect();
assert_eq!(keys[0], Codec::Identity); assert_eq!(keys[1], Codec::Sha2256); assert_eq!(keys[2], Codec::Ed25519Pub); }
#[test]
fn test_codec_in_option() {
let some_codec: Option<Codec> = Some(Codec::Sha2256);
let no_codec: Option<Codec> = None;
assert_eq!(some_codec.map(|c| c.code()), Some(0x12));
assert!(no_codec.is_none());
let codes: Option<u64> = some_codec.map(|c| c.code());
assert_eq!(codes, Some(0x12));
}
#[test]
fn test_codec_in_result() {
let ok_codec: Result<Codec, Error> = Ok(Codec::Sha2256);
let err_codec: Result<Codec, Error> = Err(Error::invalid_name("bad"));
assert_eq!(ok_codec.as_ref().unwrap().code(), 0x12);
assert!(err_codec.is_err());
let codes: Result<u64, Error> = ok_codec.map(|c| c.code());
assert_eq!(codes.unwrap(), 0x12);
}
#[test]
fn test_codec_in_vec() {
let codecs = [Codec::Identity, Codec::Sha2256, Codec::Ed25519Pub];
assert_eq!(codecs.len(), 3);
assert_eq!(codecs[0], Codec::Identity);
assert_eq!(codecs[1].code(), 0x12);
assert_eq!(codecs[2].as_str(), "ed25519-pub");
let codes: Vec<u64> = codecs.iter().map(|c| c.code()).collect();
assert_eq!(codes, vec![0x00, 0x12, 0xED]);
}
#[test]
fn test_multitrait_integration() {
let codec = Codec::Sha2256;
let encoded: Vec<u8> = codec.into();
assert!(!encoded.is_empty());
let (decoded, remaining) = Codec::try_decode_from(&encoded).unwrap();
assert_eq!(decoded, codec);
assert!(remaining.is_empty());
}
#[test]
fn test_error_handling_scenarios() {
match Codec::try_from("unknown-algorithm") {
Ok(_) => panic!("Should have failed"),
Err(e) => {
assert_eq!(e.kind(), "InvalidName");
assert!(e.to_string().contains("unknown-algorithm"));
}
}
match Codec::try_from(0xDEADBEEFu64) {
Ok(_) => panic!("Should have failed"),
Err(e) => {
assert_eq!(e.kind(), "InvalidValue");
assert!(e.to_string().contains("deadbeef"));
}
}
match Codec::try_from(-42i64) {
Ok(_) => panic!("Should have failed"),
Err(e) => {
assert_eq!(e.kind(), "NegativeValue");
assert!(e.to_string().contains("-42"));
}
}
}
#[test]
fn test_codec_registry() {
use std::collections::HashMap;
let mut registry = HashMap::new();
let codecs = vec![
Codec::Identity,
Codec::Sha2256,
Codec::Sha2512,
Codec::Ed25519Pub,
];
for codec in codecs {
registry.insert(codec.as_str().to_string(), codec.code());
}
assert_eq!(registry.get("sha2-256"), Some(&0x12));
assert_eq!(registry.get("ed25519-pub"), Some(&0xED));
assert_eq!(registry.get("unknown"), None);
}
#[test]
fn test_sequential_encoding() {
use multi_trait::EncodeIntoBuffer;
let codecs = vec![Codec::Identity, Codec::Sha2256, Codec::Ed25519Pub];
let mut buffer = Vec::new();
for codec in &codecs {
let code: u64 = (*codec).into();
code.encode_into_buffer(&mut buffer);
}
let mut remaining = buffer.as_slice();
for codec in &codecs {
let (code, rest) = u64::try_decode_from(remaining).unwrap();
let decoded = Codec::try_from(code).unwrap();
assert_eq!(decoded, *codec);
remaining = rest;
}
assert!(remaining.is_empty());
}
#[test]
fn test_pattern_matching() {
let codec = Codec::Sha2256;
match codec {
Codec::Identity => panic!("Wrong variant"),
Codec::Sha2256 => {
assert_eq!(codec.code(), 0x12);
}
_ => panic!("Wrong variant"),
}
}
#[test]
fn test_display_format() {
let codec = Codec::Ed25519Pub;
let display = format!("{}", codec);
assert_eq!(display, "ed25519-pub");
let debug = format!("{:?}", codec);
assert!(debug.contains("ed25519-pub"));
assert!(debug.contains("0xed"));
}
#[cfg(feature = "serde")]
mod serde_integration {
use super::*;
use serde::{Deserialize, Serialize};
#[test]
fn test_codec_in_serde_struct() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct CryptoOperation {
algorithm: Codec,
key_id: u64,
data: Vec<u8>,
}
let op = CryptoOperation {
algorithm: Codec::Ed25519Pub,
key_id: 42,
data: vec![1, 2, 3, 4, 5],
};
let json = serde_json::to_string(&op).unwrap();
let decoded: CryptoOperation = serde_json::from_str(&json).unwrap();
assert_eq!(decoded, op);
assert_eq!(decoded.algorithm, Codec::Ed25519Pub);
assert_eq!(decoded.algorithm.code(), 0xED);
let bytes = serde_cbor::to_vec(&op).unwrap();
let decoded: CryptoOperation = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(decoded, op);
}
#[test]
fn test_codec_in_nested_struct() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Inner {
hash_algorithm: Codec,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Outer {
signature_algorithm: Codec,
hash_config: Inner,
}
let config = Outer {
signature_algorithm: Codec::Ed25519Pub,
hash_config: Inner {
hash_algorithm: Codec::Sha2256,
},
};
let json = serde_json::to_string(&config).unwrap();
let decoded: Outer = serde_json::from_str(&json).unwrap();
assert_eq!(decoded, config);
let bytes = serde_cbor::to_vec(&config).unwrap();
let decoded: Outer = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(decoded, config);
}
}