2019-05-24 10:25:55 +02:00
|
|
|
use crate::common::*;
|
|
|
|
|
2020-02-11 12:08:57 +01:00
|
|
|
#[skip_serializing_none]
|
|
|
|
#[derive(Deserialize, Serialize, Debug, PartialEq)]
|
2020-02-04 17:51:56 +01:00
|
|
|
pub(crate) struct Metainfo {
|
|
|
|
pub(crate) announce: String,
|
2020-02-04 16:55:50 +01:00
|
|
|
#[serde(rename = "announce-list")]
|
2020-02-11 12:08:57 +01:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default, with = "inner")]
|
2020-02-04 17:51:56 +01:00
|
|
|
pub(crate) announce_list: Option<Vec<Vec<String>>>,
|
2020-02-11 12:08:57 +01:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default, with = "inner")]
|
2020-02-04 17:51:56 +01:00
|
|
|
pub(crate) comment: Option<String>,
|
2019-05-24 10:25:55 +02:00
|
|
|
#[serde(rename = "created by")]
|
2020-02-11 12:08:57 +01:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default, with = "inner")]
|
2020-02-04 17:51:56 +01:00
|
|
|
pub(crate) created_by: Option<String>,
|
2019-05-24 10:25:55 +02:00
|
|
|
#[serde(rename = "creation date")]
|
2020-02-11 12:08:57 +01:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default, with = "inner")]
|
2020-02-04 17:51:56 +01:00
|
|
|
pub(crate) creation_date: Option<u64>,
|
2020-02-11 12:08:57 +01:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none", default, with = "inner")]
|
2020-02-04 17:51:56 +01:00
|
|
|
pub(crate) encoding: Option<String>,
|
|
|
|
pub(crate) info: Info,
|
2019-05-24 10:25:55 +02:00
|
|
|
}
|
2020-02-04 16:55:50 +01:00
|
|
|
|
|
|
|
impl Metainfo {
|
2020-02-11 12:08:57 +01:00
|
|
|
#[cfg(test)]
|
|
|
|
pub(crate) fn load(path: impl AsRef<Path>) -> Result<Metainfo, Error> {
|
2020-02-04 16:55:50 +01:00
|
|
|
let path = path.as_ref();
|
|
|
|
let bytes = fs::read(path).context(error::Filesystem { path })?;
|
|
|
|
Self::deserialize(path, &bytes)
|
|
|
|
}
|
|
|
|
|
2020-02-04 19:54:41 +01:00
|
|
|
#[cfg(test)]
|
2020-02-04 16:55:50 +01:00
|
|
|
pub(crate) fn dump(&self, path: impl AsRef<Path>) -> Result<(), Error> {
|
|
|
|
let path = path.as_ref();
|
2020-02-11 12:08:57 +01:00
|
|
|
let bendy = bendy::serde::ser::to_bytes(&self).context(error::MetainfoSerialize)?;
|
|
|
|
let serde_bencode = serde_bencode::ser::to_bytes(&self).unwrap();
|
|
|
|
if bendy != serde_bencode {
|
|
|
|
panic!(
|
|
|
|
"Serialize bendy != serde_bencode:\n{}\n{}",
|
|
|
|
String::from_utf8_lossy(&bendy),
|
|
|
|
String::from_utf8_lossy(&serde_bencode)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
fs::write(path, &bendy).context(error::Filesystem { path })?;
|
2020-02-04 16:55:50 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn deserialize(path: impl AsRef<Path>, bytes: &[u8]) -> Result<Metainfo, Error> {
|
|
|
|
let path = path.as_ref();
|
2020-02-11 12:08:57 +01:00
|
|
|
let bendy = bendy::serde::de::from_bytes(&bytes).context(error::MetainfoLoad { path })?;
|
|
|
|
let serde_bencode = serde_bencode::de::from_bytes(&bytes).unwrap();
|
|
|
|
assert_eq!(bendy, serde_bencode);
|
|
|
|
Ok(bendy)
|
2020-02-04 16:55:50 +01:00
|
|
|
}
|
2020-02-04 17:36:00 +01:00
|
|
|
|
|
|
|
pub(crate) fn serialize(&self) -> Result<Vec<u8>, Error> {
|
2020-02-11 12:08:57 +01:00
|
|
|
let bendy = bendy::serde::ser::to_bytes(&self).context(error::MetainfoSerialize)?;
|
|
|
|
let serde_bencode = serde_bencode::ser::to_bytes(&self).unwrap();
|
|
|
|
if bendy != serde_bencode {
|
|
|
|
panic!(
|
|
|
|
"Serialize bendy != serde_bencode:\n{}\n{}",
|
|
|
|
String::from_utf8_lossy(&bendy),
|
|
|
|
String::from_utf8_lossy(&serde_bencode)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
Ok(bendy)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub(crate) fn from_bytes(bytes: &[u8]) -> Metainfo {
|
|
|
|
let bendy = bendy::serde::de::from_bytes(bytes).unwrap();
|
|
|
|
let serde_bencode = serde_bencode::de::from_bytes(bytes).unwrap();
|
|
|
|
assert_eq!(bendy, serde_bencode);
|
|
|
|
bendy
|
2020-02-04 17:36:00 +01:00
|
|
|
}
|
2020-02-04 16:55:50 +01:00
|
|
|
}
|