diff options
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/examples/encrypt-for.rs | 4 | ||||
-rw-r--r-- | openpgp/examples/sign.rs | 3 | ||||
-rw-r--r-- | openpgp/src/constants.rs | 115 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 3 | ||||
-rw-r--r-- | openpgp/src/literal.rs | 15 | ||||
-rw-r--r-- | openpgp/src/message.rs | 39 | ||||
-rw-r--r-- | openpgp/src/packet_pile.rs | 24 | ||||
-rw-r--r-- | openpgp/src/parse/parse.rs | 11 | ||||
-rw-r--r-- | openpgp/src/serialize/mod.rs | 38 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 55 |
10 files changed, 222 insertions, 85 deletions
diff --git a/openpgp/examples/encrypt-for.rs b/openpgp/examples/encrypt-for.rs index 5fe9360f..9e5c2cdf 100644 --- a/openpgp/examples/encrypt-for.rs +++ b/openpgp/examples/encrypt-for.rs @@ -5,6 +5,7 @@ use std::io; extern crate openpgp; use openpgp::armor; +use openpgp::constants::DataFormat; use openpgp::serialize::stream::{ wrap, LiteralWriter, Encryptor, EncryptionMode, }; @@ -47,7 +48,8 @@ fn main() { &recipients, mode) .expect("Failed to create encryptor"); - let mut literal_writer = LiteralWriter::new(encryptor, 't', None, None) + let mut literal_writer = LiteralWriter::new(encryptor, DataFormat::Binary, + None, None) .expect("Failed to create literal writer"); // Finally, copy stdin to our writer stack to encrypt the data. diff --git a/openpgp/examples/sign.rs b/openpgp/examples/sign.rs index 1d2376c2..a071dacf 100644 --- a/openpgp/examples/sign.rs +++ b/openpgp/examples/sign.rs @@ -5,6 +5,7 @@ use std::io; extern crate openpgp; use openpgp::armor; +use openpgp::constants::DataFormat; use openpgp::serialize::stream::{wrap, LiteralWriter, Signer}; fn main() { @@ -37,7 +38,7 @@ fn main() { // Then, create a literal writer to wrap the data in a literal // message packet. - let mut literal = LiteralWriter::new(signer, 'b', None, None) + let mut literal = LiteralWriter::new(signer, DataFormat::Binary, None, None) .expect("Failed to create literal writer"); // Finally, just copy all the data. diff --git a/openpgp/src/constants.rs b/openpgp/src/constants.rs index bf41e428..05260d0b 100644 --- a/openpgp/src/constants.rs +++ b/openpgp/src/constants.rs @@ -753,6 +753,97 @@ impl Arbitrary for ReasonForRevocation { } } + +/// Describes the format of the body of a literal data packet. +/// +/// See the description of literal data packets [Section 5.9 of RFC 4880]. +/// +/// [Section 5.9 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.9 +#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord)] +pub enum DataFormat { + /// Binary data. + Binary, + + /// Text data. + Text, + + /// Text data, probably valid UTF-8. + Unicode, + + /// MIME message. + /// + /// This is defined in [Section 5.10 of RFC4880bis]. + /// + /// [Section 5.10 of RFC4880bis]: https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.10 + MIME, + + /// Unknown format specifier. + Unknown(char), +} + +impl From<u8> for DataFormat { + fn from(u: u8) -> Self { + (u as char).into() + } +} + +impl From<char> for DataFormat { + fn from(c: char) -> Self { + use self::DataFormat::*; + match c { + 'b' => Binary, + 't' => Text, + 'u' => Unicode, + 'm' => MIME, + c => Unknown(c), + } + } +} + +impl From<DataFormat> for u8 { + fn from(f: DataFormat) -> u8 { + char::from(f) as u8 + } +} + +impl From<DataFormat> for char { + fn from(f: DataFormat) -> char { + use self::DataFormat::*; + match f { + Binary => 'b', + Text => 't', + Unicode => 'u', + MIME => 'm', + Unknown(c) => c, + } + } +} + +impl fmt::Display for DataFormat { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::DataFormat::*; + match *self { + Binary => + f.write_str("Binary data"), + Text => + f.write_str("Text data"), + Unicode => + f.write_str("Text data (UTF-8)"), + MIME => + f.write_str("MIME message body part"), + Unknown(c) => + f.write_fmt(format_args!( + "Unknown data format identifier {:?}", c)), + } + } +} + +impl Arbitrary for DataFormat { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + u8::arbitrary(g).into() + } +} + #[cfg(test)] mod tests { use super::*; @@ -922,4 +1013,28 @@ mod tests { } } } + + quickcheck! { + fn df_roundtrip(df: DataFormat) -> bool { + let val: u8 = df.clone().into(); + df == DataFormat::from(val) + } + } + + quickcheck! { + fn df_display(df: DataFormat) -> bool { + let s = format!("{}", df); + !s.is_empty() + } + } + + quickcheck! { + fn df_parse(df: DataFormat) -> bool { + match df { + DataFormat::Unknown(u) => + u != 'b' && u != 't' && u != 'u' && u != 'm', + _ => true + } + } + } } diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index 01b059f2..fb727b2e 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -107,6 +107,7 @@ mod message; pub mod constants; use constants::{ + DataFormat, PublicKeyAlgorithm, SymmetricAlgorithm, CompressionAlgorithm, @@ -381,7 +382,7 @@ pub struct Literal { /// CTB packet header fields. pub common: packet::Common, /// A one-octet field that describes how the data is formatted. - pub format: u8, + pub format: DataFormat, /// filename is a string, but strings in Rust are valid UTF-8. /// There is no guarantee, however, that the filename is valid /// UTF-8. Thus, we leave filename as a byte array. It can be diff --git a/openpgp/src/literal.rs b/openpgp/src/literal.rs index 3b66d0c1..70581375 100644 --- a/openpgp/src/literal.rs +++ b/openpgp/src/literal.rs @@ -2,6 +2,7 @@ use std::fmt; use std::cmp; use time; +use constants::DataFormat; use conversions::Time; use Literal; use Packet; @@ -29,7 +30,7 @@ impl fmt::Debug for Literal { prefix_fmt.push_str(&format!(" ({} bytes)", body.len())[..]); f.debug_struct("Literal") - .field("format", &(self.format as char)) + .field("format", &self.format) .field("filename", &filename) .field("date", &self.date) .field("body", &prefix_fmt) @@ -39,10 +40,10 @@ impl fmt::Debug for Literal { impl Literal { /// Returns a new `Literal` packet. - pub fn new(format: char) -> Literal { + pub fn new(format: DataFormat) -> Literal { Literal { common: Default::default(), - format: format as u8, + format: format, filename: None, date: time::Tm::from_pgp(0), } @@ -59,7 +60,7 @@ impl Literal { /// This is a hint that the content is probably text; the encoding /// is not specified. pub fn text(mut self) -> Literal { - self.format = 't' as u8; + self.format = DataFormat::Text; self } @@ -67,7 +68,7 @@ impl Literal { /// /// This is a hint that the content is probably UTF-8 encoded. pub fn utf8(mut self) -> Literal { - self.format = 'u' as u8; + self.format = DataFormat::Unicode; self } @@ -75,7 +76,7 @@ impl Literal { /// /// This is a hint that the content is probably binary data. pub fn binary(mut self) -> Literal { - self.format = 'b' as u8; + self.format = DataFormat::Binary; self } @@ -84,7 +85,7 @@ impl Literal { /// This is specified in RFC 4880bis, which has not yet been /// standardized. pub fn mime(mut self) -> Literal { - self.format = 'm' as u8; + self.format = DataFormat::MIME; self } diff --git a/openpgp/src/message.rs b/openpgp/src/message.rs index 6207f23b..dc2148a4 100644 --- a/openpgp/src/message.rs +++ b/openpgp/src/message.rs @@ -257,6 +257,7 @@ impl Message { mod tests { use super::*; + use constants::DataFormat::Text; use HashAlgorithm; use CompressionAlgorithm; use SymmetricAlgorithm; @@ -284,7 +285,7 @@ mod tests { // 0: Literal // => good. let mut packets = Vec::new(); - packets.push(Literal::new('t').body(b"data".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"data".to_vec()).to_packet()); let message = Message::from_packets(packets); assert!(message.is_ok(), "{:?}", message); @@ -298,7 +299,7 @@ mod tests { let mut packets = Vec::new(); packets.push( CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"inner".to_vec()).to_packet()) + .push(Literal::new(Text).body(b"inner".to_vec()).to_packet()) .to_packet()); let message = Message::from_packets(packets); @@ -311,8 +312,8 @@ mod tests { let mut packets = Vec::new(); packets.push( CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"inner one".to_vec()).to_packet()) - .push(Literal::new('t').body(b"inner two".to_vec()).to_packet()) + .push(Literal::new(Text).body(b"inner one".to_vec()).to_packet()) + .push(Literal::new(Text).body(b"inner two".to_vec()).to_packet()) .to_packet()); let message = Message::from_packets(packets); @@ -325,9 +326,9 @@ mod tests { let mut packets = Vec::new(); packets.push( CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"inner".to_vec()).to_packet()) + .push(Literal::new(Text).body(b"inner".to_vec()).to_packet()) .to_packet()); - packets.push(Literal::new('t').body(b"outer".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"outer".to_vec()).to_packet()); let message = Message::from_packets(packets); assert!(message.is_err(), "{:?}", message); @@ -340,7 +341,7 @@ mod tests { packets.push( CompressedData::new(CompressionAlgorithm::Uncompressed) .push(CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"inner".to_vec()) + .push(Literal::new(Text).body(b"inner".to_vec()) .to_packet()) .to_packet()) .to_packet()); @@ -364,7 +365,7 @@ mod tests { // => bad. let mut packets : Vec<Packet> = Vec::new(); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); let message = Message::from_packets(packets); assert!(message.is_err(), "{:?}", message); @@ -375,7 +376,7 @@ mod tests { // => good. let mut packets : Vec<Packet> = Vec::new(); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); let message = Message::from_packets(packets); @@ -388,7 +389,7 @@ mod tests { // => bad. let mut packets : Vec<Packet> = Vec::new(); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); @@ -404,7 +405,7 @@ mod tests { let mut packets : Vec<Packet> = Vec::new(); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); @@ -421,8 +422,8 @@ mod tests { let mut packets : Vec<Packet> = Vec::new(); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); @@ -441,7 +442,7 @@ mod tests { packets.push(OnePassSig::new(SignatureType::Binary).to_packet()); packets.push( CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"inner".to_vec()).to_packet()) + .push(Literal::new(Text).body(b"inner".to_vec()).to_packet()) .to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); @@ -465,7 +466,7 @@ mod tests { // => good. let mut packets : Vec<Packet> = Vec::new(); packets.push(Signature::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); let message = Message::from_packets(packets); assert!(message.is_ok(), "{:?}", message); @@ -477,7 +478,7 @@ mod tests { let mut packets : Vec<Packet> = Vec::new(); packets.push(Signature::new(SignatureType::Binary).to_packet()); packets.push(Signature::new(SignatureType::Binary).to_packet()); - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); let message = Message::from_packets(packets); assert!(message.is_ok(), "{:?}", message); @@ -504,7 +505,7 @@ mod tests { // 0: SK-ESK // 1: Literal // => bad. - packets.push(Literal::new('t').body(b"inner".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"inner".to_vec()).to_packet()); assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>() == [ Tag::SKESK, Tag::Literal ]); @@ -522,7 +523,7 @@ mod tests { }; seip.common.children = Some(Container::new()); seip.common.children.as_mut().unwrap().push( - Literal::new('t').body(b"inner".to_vec()).to_packet()); + Literal::new(Text).body(b"inner".to_vec()).to_packet()); packets[1] = Packet::SEIP(seip); assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>() @@ -597,7 +598,7 @@ mod tests { // => bad. packets.remove(3); packets[2].children.as_mut().unwrap().push( - Literal::new('t').body(b"inner two".to_vec()).to_packet()); + Literal::new(Text).body(b"inner two".to_vec()).to_packet()); assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>() == [ Tag::SKESK, Tag::SKESK, Tag::SEIP ]); diff --git a/openpgp/src/packet_pile.rs b/openpgp/src/packet_pile.rs index c910f538..aa42aac9 100644 --- a/openpgp/src/packet_pile.rs +++ b/openpgp/src/packet_pile.rs @@ -159,7 +159,7 @@ impl PacketPile { /// /// ```rust /// # extern crate openpgp; - /// # use openpgp::{Result, constants::CompressionAlgorithm, + /// # use openpgp::{Result, constants::{CompressionAlgorithm, DataFormat}, /// # Packet, PacketPile, Literal, CompressedData}; /// /// # fn main() { f().unwrap(); } @@ -167,13 +167,14 @@ impl PacketPile { /// // A compressed data packet that contains a literal data packet. /// let mut pile = PacketPile::from_packet( /// CompressedData::new(CompressionAlgorithm::Uncompressed) - /// .push(Literal::new('t').body(b"old".to_vec()).to_packet()) + /// .push(Literal::new(DataFormat::Text).body(b"old".to_vec()) + /// .to_packet()) /// .to_packet()); /// /// // Replace the literal data packet. /// pile.replace( /// &[ 0, 0 ], 1, - /// [ Literal::new('t').body(b"new".to_vec()).to_packet() ] + /// [ Literal::new(DataFormat::Text).body(b"new".to_vec()).to_packet() ] /// .to_vec()) /// .unwrap(); /// # if let Some(Packet::Literal(lit)) = pile.path_ref(&[0, 0]) { @@ -430,6 +431,7 @@ mod message_test { use super::*; use CompressionAlgorithm; + use constants::DataFormat::Text; use Literal; use CompressedData; use SEIP; @@ -648,7 +650,7 @@ mod message_test { let mut cd = CompressedData::new(CompressionAlgorithm::Uncompressed); for t in text.iter() { - cd = cd.push(Literal::new('t').body(t.to_vec()).to_packet()) + cd = cd.push(Literal::new(Text).body(t.to_vec()).to_packet()) } let mut seip = SEIP { @@ -714,7 +716,7 @@ mod message_test { // => // 0: Literal("two") let mut packets : Vec<Packet> = Vec::new(); - packets.push(Literal::new('t').body(b"one".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"one".to_vec()).to_packet()); assert!(packets.iter().map(|p| p.tag()).collect::<Vec<Tag>>() == [ Tag::Literal ]); @@ -722,7 +724,7 @@ mod message_test { let mut pile = PacketPile::from_packets(packets.clone()); pile.replace( &[ 0 ], 1, - [ Literal::new('t').body(b"two".to_vec()).to_packet() + [ Literal::new(Text).body(b"two".to_vec()).to_packet() ].to_vec()).unwrap(); let children = pile.into_children().collect::<Vec<Packet>>(); @@ -743,7 +745,7 @@ mod message_test { let mut packets : Vec<Packet> = Vec::new(); for text in initial.iter() { - packets.push(Literal::new('t').body(text.to_vec()).to_packet()) + packets.push(Literal::new(Text).body(text.to_vec()).to_packet()) } for start in 0..initial.len() + 1 { @@ -754,7 +756,7 @@ mod message_test { let mut replacement : Vec<Packet> = Vec::new(); for &text in inserted[0..insert].iter() { replacement.push( - Literal::new('t').body(text.to_vec()).to_packet()) + Literal::new(Text).body(text.to_vec()).to_packet()) } pile.replace(&[ start ], delete, replacement).unwrap(); @@ -793,7 +795,7 @@ mod message_test { let mut cd = CompressedData::new(CompressionAlgorithm::Uncompressed); for l in initial.iter() { - cd = cd.push(Literal::new('t').body(l.to_vec()).to_packet()) + cd = cd.push(Literal::new(Text).body(l.to_vec()).to_packet()) } for start in 0..initial.len() + 1 { @@ -805,7 +807,7 @@ mod message_test { let mut replacement : Vec<Packet> = Vec::new(); for &text in inserted[0..insert].iter() { replacement.push( - Literal::new('t').body(text.to_vec()).to_packet()) + Literal::new(Text).body(text.to_vec()).to_packet()) } pile.replace(&[ 0, start ], delete, replacement).unwrap(); @@ -838,7 +840,7 @@ mod message_test { // Make sure out-of-range accesses error out. let mut packets : Vec<Packet> = Vec::new(); - packets.push(Literal::new('t').body(b"one".to_vec()).to_packet()); + packets.push(Literal::new(Text).body(b"one".to_vec()).to_packet()); let mut pile = PacketPile::from_packets(packets.clone()); assert!(pile.replace(&[ 1 ], 0, Vec::new()).is_ok()); diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse/parse.rs index 26af6449..6e36adce 100644 --- a/openpgp/src/parse/parse.rs +++ b/openpgp/src/parse/parse.rs @@ -1114,7 +1114,7 @@ impl Literal { let recursion_depth = php.recursion_depth; let mut pp = php.ok(Packet::Literal(Literal { common: Default::default(), - format: format, + format: format.into(), filename: filename, date: time::Tm::from_pgp(date), }))?; @@ -1128,6 +1128,7 @@ impl Literal { #[test] fn literal_parser_test () { + use constants::DataFormat; { let data = bytes!("literal-mode-b.gpg"); let mut pp = PacketParser::from_bytes(data).unwrap().unwrap(); @@ -1136,7 +1137,7 @@ fn literal_parser_test () { let p = pp.finish().unwrap(); // eprintln!("{:?}", p); if let &Packet::Literal(ref p) = p { - assert_eq!(p.format, 'b' as u8); + assert_eq!(p.format, DataFormat::Binary); assert_eq!(p.filename.as_ref().unwrap()[..], b"foobar"[..]); assert_eq!(p.date, time::Tm::from_pgp(1507458744)); assert_eq!(content, b"FOOBAR"); @@ -1152,7 +1153,7 @@ fn literal_parser_test () { let content = pp.steal_eof().unwrap(); let p = pp.finish().unwrap(); if let &Packet::Literal(ref p) = p { - assert_eq!(p.format, 't' as u8); + assert_eq!(p.format, DataFormat::Text); assert_eq!(p.filename.as_ref().unwrap()[..], b"manifesto.txt"[..]); assert_eq!(p.date, time::Tm::from_pgp(1508000649)); @@ -1234,6 +1235,8 @@ impl CompressedData { #[cfg(any(feature = "compression-deflate", feature = "compression-bzip2"))] #[test] fn compressed_data_parser_test () { + use constants::DataFormat; + let expected = bytes!("a-cypherpunks-manifesto.txt"); for i in 1..4 { @@ -1269,7 +1272,7 @@ fn compressed_data_parser_test () { if let Packet::Literal(literal) = literal { assert_eq!(literal.filename, None); - assert_eq!(literal.format, 'b' as u8); + assert_eq!(literal.format, DataFormat::Binary); assert_eq!(literal.date, time::Tm::from_pgp(1509219866)); assert_eq!(content, expected.to_vec()); } else { diff --git a/openpgp/src/serialize/mod.rs b/openpgp/src/serialize/mod.rs index 235bbd6d..fc0a2c1f 100644 --- a/openpgp/src/serialize/mod.rs +++ b/openpgp/src/serialize/mod.rs @@ -768,7 +768,7 @@ impl Literal { CTB::new(Tag::Literal).serialize(o)?; BodyLength::Full(len as u32).serialize(o)?; } - write_byte(o, self.format)?; + write_byte(o, self.format.into())?; write_byte(o, filename.len() as u8)?; o.write_all(filename)?; write_be_u32(o, self.date.to_pgp()?)?; @@ -1303,6 +1303,8 @@ mod serialize_test { // reparse them, and make sure we get the same result. #[test] fn serialize_test_3() { + use constants::DataFormat::Text as T; + // serialize_test_1 and serialize_test_2 parse a byte stream. // This tests creates the message, and then serializes and // reparses it. @@ -1316,10 +1318,10 @@ mod serialize_test { let mut top_level = Vec::new(); top_level.push( CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"one".to_vec()).to_packet()) - .push(Literal::new('t').body(b"two".to_vec()).to_packet()) + .push(Literal::new(T).body(b"one".to_vec()).to_packet()) + .push(Literal::new(T).body(b"two".to_vec()).to_packet()) .to_packet()); - top_level.push(Literal::new('t').body(b"three".to_vec()).to_packet()); + top_level.push(Literal::new(T).body(b"three".to_vec()).to_packet()); messages.push(top_level); // 1: CompressedData(CompressedData { algo: 0 }) @@ -1333,12 +1335,12 @@ mod serialize_test { top_level.push( CompressedData::new(CompressionAlgorithm::Uncompressed) .push(CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"one".to_vec()).to_packet()) - .push(Literal::new('t').body(b"two".to_vec()).to_packet()) + .push(Literal::new(T).body(b"one".to_vec()).to_packet()) + .push(Literal::new(T).body(b"two".to_vec()).to_packet()) .to_packet()) .push(CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"three".to_vec()).to_packet()) - .push(Literal::new('t').body(b"four".to_vec()).to_packet()) + .push(Literal::new(T).body(b"three".to_vec()).to_packet()) + .push(Literal::new(T).body(b"four".to_vec()).to_packet()) .to_packet()) .to_packet()); messages.push(top_level); @@ -1359,16 +1361,16 @@ mod serialize_test { .push(CompressedData::new(CompressionAlgorithm::Uncompressed) .push(CompressedData::new(CompressionAlgorithm::Uncompressed) .push(CompressedData::new(CompressionAlgorithm::Uncompressed) - .push(Literal::new('t').body(b"one".to_vec()).to_packet()) - .push(Literal::new('t').body(b"two".to_vec()).to_packet()) + .push(Literal::new(T).bod |