irontide_bencode/
value.rs1use std::collections::BTreeMap;
2use std::fmt;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum BencodeValue {
10 Integer(i64),
12 Bytes(Vec<u8>),
14 List(Vec<BencodeValue>),
16 Dict(BTreeMap<Vec<u8>, BencodeValue>),
18}
19
20impl BencodeValue {
21 pub fn as_int(&self) -> Option<i64> {
23 match self {
24 BencodeValue::Integer(n) => Some(*n),
25 _ => None,
26 }
27 }
28
29 pub fn as_bytes_raw(&self) -> Option<&[u8]> {
31 match self {
32 BencodeValue::Bytes(b) => Some(b),
33 _ => None,
34 }
35 }
36
37 pub fn as_list(&self) -> Option<&[BencodeValue]> {
39 match self {
40 BencodeValue::List(items) => Some(items),
41 _ => None,
42 }
43 }
44
45 pub fn as_dict(&self) -> Option<&BTreeMap<Vec<u8>, BencodeValue>> {
47 match self {
48 BencodeValue::Dict(map) => Some(map),
49 _ => None,
50 }
51 }
52}
53
54impl fmt::Display for BencodeValue {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 match self {
57 BencodeValue::Integer(n) => write!(f, "{n}"),
58 BencodeValue::Bytes(b) => match std::str::from_utf8(b) {
59 Ok(s) => write!(f, "\"{s}\""),
60 Err(_) => write!(f, "<{} bytes>", b.len()),
61 },
62 BencodeValue::List(items) => {
63 write!(f, "[")?;
64 for (i, item) in items.iter().enumerate() {
65 if i > 0 {
66 write!(f, ", ")?;
67 }
68 write!(f, "{item}")?;
69 }
70 write!(f, "]")
71 }
72 BencodeValue::Dict(map) => {
73 write!(f, "{{")?;
74 for (i, (key, val)) in map.iter().enumerate() {
75 if i > 0 {
76 write!(f, ", ")?;
77 }
78 match std::str::from_utf8(key) {
79 Ok(s) => write!(f, "\"{s}\": {val}")?,
80 Err(_) => write!(f, "<{} bytes>: {val}", key.len())?,
81 }
82 }
83 write!(f, "}}")
84 }
85 }
86 }
87}
88
89impl serde::Serialize for BencodeValue {
90 fn serialize<S: serde::Serializer>(
91 &self,
92 serializer: S,
93 ) -> std::result::Result<S::Ok, S::Error> {
94 match self {
95 BencodeValue::Integer(n) => serializer.serialize_i64(*n),
96 BencodeValue::Bytes(b) => serializer.serialize_bytes(b),
97 BencodeValue::List(items) => {
98 use serde::ser::SerializeSeq;
99 let mut seq = serializer.serialize_seq(Some(items.len()))?;
100 for item in items {
101 seq.serialize_element(item)?;
102 }
103 seq.end()
104 }
105 BencodeValue::Dict(map) => {
106 use serde::ser::SerializeMap;
107 let mut m = serializer.serialize_map(Some(map.len()))?;
108 for (key, val) in map {
109 m.serialize_entry(&serde_bytes::Bytes::new(key), val)?;
110 }
111 m.end()
112 }
113 }
114 }
115}
116
117impl<'de> serde::Deserialize<'de> for BencodeValue {
118 fn deserialize<D: serde::Deserializer<'de>>(
119 deserializer: D,
120 ) -> std::result::Result<Self, D::Error> {
121 deserializer.deserialize_any(BencodeValueVisitor)
122 }
123}
124
125struct BencodeValueVisitor;
126
127impl<'de> serde::de::Visitor<'de> for BencodeValueVisitor {
128 type Value = BencodeValue;
129
130 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 write!(f, "a bencode value")
132 }
133
134 fn visit_i64<E: serde::de::Error>(self, v: i64) -> std::result::Result<Self::Value, E> {
135 Ok(BencodeValue::Integer(v))
136 }
137
138 fn visit_u64<E: serde::de::Error>(self, v: u64) -> std::result::Result<Self::Value, E> {
139 Ok(BencodeValue::Integer(v as i64))
140 }
141
142 fn visit_bytes<E: serde::de::Error>(self, v: &[u8]) -> std::result::Result<Self::Value, E> {
143 Ok(BencodeValue::Bytes(v.to_vec()))
144 }
145
146 fn visit_borrowed_bytes<E: serde::de::Error>(
147 self,
148 v: &'de [u8],
149 ) -> std::result::Result<Self::Value, E> {
150 Ok(BencodeValue::Bytes(v.to_vec()))
151 }
152
153 fn visit_str<E: serde::de::Error>(self, v: &str) -> std::result::Result<Self::Value, E> {
154 Ok(BencodeValue::Bytes(v.as_bytes().to_vec()))
155 }
156
157 fn visit_seq<A: serde::de::SeqAccess<'de>>(
158 self,
159 mut seq: A,
160 ) -> std::result::Result<Self::Value, A::Error> {
161 let mut items = Vec::new();
162 while let Some(item) = seq.next_element()? {
163 items.push(item);
164 }
165 Ok(BencodeValue::List(items))
166 }
167
168 fn visit_map<A: serde::de::MapAccess<'de>>(
169 self,
170 mut map: A,
171 ) -> std::result::Result<Self::Value, A::Error> {
172 let mut dict = BTreeMap::new();
173 while let Some((key, val)) = map.next_entry::<serde_bytes::ByteBuf, BencodeValue>()? {
174 dict.insert(key.into_vec(), val);
175 }
176 Ok(BencodeValue::Dict(dict))
177 }
178}