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