use super::{File, SourceName};
use crate::{
build_profile::BuildProfile,
control::{
Architectures, DateTime2822, Delimited, FileDigestSha1, FileDigestSha256,
PriorityParseError, SpaceDelimitedStrings,
},
version::Version,
};
pub type Closes = SpaceDelimitedStrings;
#[cfg(feature = "serde")]
use ::serde::{Deserialize, Serialize};
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ChangesParseError {
Malformed,
InvalidHashLength,
InvalidHash,
InvalidDate,
InvalidPriority(PriorityParseError),
}
crate::errors::error_enum!(ChangesParseError);
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Changes {
#[cfg_attr(feature = "serde", serde(rename = "Format"))]
pub format: String,
#[cfg_attr(feature = "serde", serde(rename = "Date"))]
pub date: DateTime2822,
#[cfg_attr(feature = "serde", serde(rename = "Source"))]
pub source: SourceName,
#[cfg_attr(feature = "serde", serde(rename = "Binary"))]
pub binary: Option<SpaceDelimitedStrings>,
#[cfg_attr(feature = "serde", serde(rename = "Architecture"))]
pub architecture: Architectures,
#[cfg_attr(feature = "serde", serde(rename = "Version"))]
pub version: Version,
#[cfg_attr(feature = "serde", serde(rename = "Distribution"))]
pub distribution: String,
#[cfg_attr(feature = "serde", serde(rename = "Urgency"))]
pub urgency: String,
#[cfg_attr(feature = "serde", serde(rename = "Maintainer"))]
pub maintainer: String,
#[cfg_attr(feature = "serde", serde(rename = "Changed-By"))]
pub changed_by: Option<String>,
#[cfg_attr(feature = "serde", serde(rename = "Description"))]
pub description: Option<String>,
#[cfg_attr(feature = "serde", serde(rename = "Closes"))]
pub closes: Option<Closes>,
#[cfg_attr(feature = "serde", serde(rename = "Binary-Only"))]
pub binary_only: Option<bool>,
#[cfg_attr(feature = "serde", serde(rename = "Built-For-Profiles"))]
pub built_for_profiles: Option<Delimited<' ', BuildProfile>>,
#[cfg_attr(feature = "serde", serde(rename = "Changes"))]
pub changes: String,
#[cfg_attr(feature = "serde", serde(rename = "Files"))]
pub files: Vec<File>,
#[cfg_attr(feature = "serde", serde(rename = "Checksums-Sha1"))]
pub checksum_sha1: Option<Vec<FileDigestSha1>>,
#[cfg_attr(feature = "serde", serde(rename = "Checksums-Sha256"))]
pub checksum_sha256: Option<Vec<FileDigestSha256>>,
}
#[cfg(feature = "serde")]
mod serde {
#[cfg(test)]
mod tests {
use crate::{
architecture,
control::{
self,
package::{Changes, File},
},
};
use std::io::{BufReader, Cursor};
#[test]
fn test_changes() {
let mut reader = BufReader::new(Cursor::new("\
Format: 1.8
Date: Mon, 26 Dec 2022 16:30:00 +0100
Source: hello
Binary: hello hello-dbgsym
Architecture: source amd64
Version: 2.10-3
Distribution: unstable
Urgency: medium
Maintainer: Santiago Vila <sanvila@debian.org>
Changed-By: Santiago Vila <sanvila@debian.org>
Description:
hello - example package based on GNU hello
Closes: 871622 893083
Changes:
hello (2.10-3) unstable; urgency=medium
.
* Add some autopkgtests. Closes: #871622.
* Add Vcs-Git and Vcs-Browser fields to debian/control. Closes: #893083.
* Raise debhelper compat level from 9 to 13. This enables autoreconf,
and as a result, some additional build-dependencies are required:
- Add texinfo to Build-Depends, for a normal build.
- Add help2man to Build-Depends, for a build using git.
* Use secure URI in Homepage field.
* Set upstream metadata fields Bug-Submit, Name and Repository-Browse.
* Add upstream signing-key.
* Use a common debian/watch file which is valid for most GNU packages.
* Sort control fields using wrap-and-sort.
* Update standards version to 4.6.2.
Checksums-Sha1:
4755bb94240986213836726f9b594e853920f541 1183 hello_2.10-3.dsc
82e477ec77f09bae910e53592d28319774754af6 12688 hello_2.10-3.debian.tar.xz
45a6ecadd0d8672ab875451c17f84067137783c8 36084 hello-dbgsym_2.10-3_amd64.deb
9a6e6d94a7bbf07e8d8f46071dbaa3fc9c0f1227 7657 hello_2.10-3_amd64.buildinfo
8439082041b2b154fdb48f98530cbdf54557abac 53324 hello_2.10-3_amd64.deb
Checksums-Sha256:
e8ba61cf5c8e2ef3107cc1c6e4fb7125064947dd5565c22cde1b9a407c6264ba 1183 hello_2.10-3.dsc
f43ddcca8d7168c5d52b53e1f2a69b78f42f8387633ef8955edd0621c73cf65c 12688 hello_2.10-3.debian.tar.xz
16990db381cd1816fc65436447dedaa3298fc29179ee7e4379e7793a7d75cacb 36084 hello-dbgsym_2.10-3_amd64.deb
ae955f1835dd9948fa6b8aaeb6f26aff21ff6501a41913ae52306aa2d627f918 7657 hello_2.10-3_amd64.buildinfo
052cb5fdfa86bb3485d6194d9ae2fd1cabbccbdd9c7da3258aed1674b288bbf9 53324 hello_2.10-3_amd64.deb
Files:
e7bd195571b19d33bd83d1c379fe6432 1183 devel optional hello_2.10-3.dsc
16678389ba7fddcdfa05e0707d61f043 12688 devel optional hello_2.10-3.debian.tar.xz
5b2bcd51a3ad0d0e611aafd9276b938e 36084 debug optional hello-dbgsym_2.10-3_amd64.deb
57144f2c9158564350da3371b5b9a542 7657 devel optional hello_2.10-3_amd64.buildinfo
d36abefbc87d8dfb7704238f0aee0e90 53324 devel optional hello_2.10-3_amd64.deb
"));
let changes: Changes = control::de::from_reader(&mut reader).unwrap();
assert_eq!("hello", changes.source.name);
assert_eq!(2, changes.binary.unwrap().len());
assert_eq!(2, changes.architecture.len());
assert_eq!(
&[architecture::SOURCE, architecture::AMD64],
changes.architecture.as_ref(),
);
assert_eq!(2, changes.closes.as_ref().unwrap().as_ref().len());
assert_eq!(
&["871622", "893083"],
changes.closes.as_ref().unwrap().as_ref()
);
assert_eq!(5, changes.files.len());
assert_eq!(
vec![
File {
digest: "e7bd195571b19d33bd83d1c379fe6432".parse().unwrap(),
size: 1183,
path: "hello_2.10-3.dsc".to_owned(),
section: "devel".to_owned(),
priority: Some("optional".parse().unwrap()),
},
File {
digest: "16678389ba7fddcdfa05e0707d61f043".parse().unwrap(),
size: 12688,
path: "hello_2.10-3.debian.tar.xz".to_owned(),
section: "devel".to_owned(),
priority: Some("optional".parse().unwrap()),
},
File {
digest: "5b2bcd51a3ad0d0e611aafd9276b938e".parse().unwrap(),
size: 36084,
path: "hello-dbgsym_2.10-3_amd64.deb".to_owned(),
section: "debug".to_owned(),
priority: Some("optional".parse().unwrap()),
},
File {
digest: "57144f2c9158564350da3371b5b9a542".parse().unwrap(),
size: 7657,
path: "hello_2.10-3_amd64.buildinfo".to_owned(),
section: "devel".to_owned(),
priority: Some("optional".parse().unwrap()),
},
File {
digest: "d36abefbc87d8dfb7704238f0aee0e90".parse().unwrap(),
size: 53324,
path: "hello_2.10-3_amd64.deb".to_owned(),
section: "devel".to_owned(),
priority: Some("optional".parse().unwrap()),
}
],
changes.files,
);
assert_eq!(changes.files.len(), changes.checksum_sha1.unwrap().len());
assert_eq!(changes.files.len(), changes.checksum_sha256.unwrap().len());
}
}
}