debian_control/lossy/
buildinfo.rs1use crate::lossy::relations::Relations;
7use deb822_fast::FromDeb822Paragraph;
8use deb822_fast::{FromDeb822, ToDeb822};
9use std::collections::HashMap;
10use std::path::PathBuf;
11
12fn deserialize_env(s: &str) -> Result<HashMap<String, String>, String> {
13 let mut env = HashMap::new();
14 for line in s.lines() {
15 if line.trim().is_empty() {
16 continue;
17 }
18 let (key, value) = match line.split_once("=") {
19 Some((key, value)) => {
20 if value.len() >= 2 && value.starts_with('"') && value.ends_with('"') {
23 let value = value[1..value.len() - 1].to_string();
24 (key, value)
25 } else {
26 (key, value.to_string())
27 }
28 }
29 None => {
30 return Err("Invalid environment variable".to_string());
32 }
33 };
34 env.insert(key.to_string(), value.to_string());
35 }
36 Ok(env)
37}
38
39fn serialize_env(env: &HashMap<String, String>) -> String {
40 let mut s = String::new();
41 for (key, value) in env {
42 s.push_str(&format!("{}={}\n", key, value));
43 }
44 s
45}
46
47fn deserialize_version(s: &str) -> Result<debversion::Version, String> {
48 s.parse().map_err(|e: debversion::ParseError| e.to_string())
49}
50
51fn serialize_version(version: &debversion::Version) -> String {
52 version.to_string()
53}
54
55fn serialize_pathbuf(path: &std::path::Path) -> String {
56 path.display().to_string()
57}
58
59fn deserialize_pathbuf(s: &str) -> Result<PathBuf, String> {
60 Ok(PathBuf::from(s))
61}
62
63#[derive(FromDeb822, ToDeb822)]
64pub struct Buildinfo {
66 #[deb822(field = "Format")]
67 format: String,
69
70 #[deb822(field = "Build-Architecture")]
71 build_architecture: String,
73
74 #[deb822(field = "Source")]
75 source: String,
77
78 #[deb822(field = "Binary")]
79 binary: Option<String>,
81
82 #[deb822(field = "Architecture")]
83 architecture: String,
85
86 #[deb822(
87 field = "Version",
88 deserialize_with = deserialize_version,
89 serialize_with = serialize_version
90 )]
91 version: debversion::Version,
93
94 #[deb822(field = "Binary-Only-Changes")]
95 binary_only_changes: Option<String>,
96
97 #[deb822(field = "Checksums-Sha256")]
98 checksums_sha256: Option<String>,
101
102 #[deb822(field = "Checksums-Sha1")]
103 checksums_sha1: Option<String>,
106
107 #[deb822(field = "Checksums-Md5")]
108 checksums_md5: Option<String>,
111
112 #[deb822(field = "Build-Origin")]
113 build_origin: Option<String>,
115
116 #[deb822(field = "Build-Date")]
117 build_date: Option<String>,
119
120 #[deb822(field = "Build-Tainted-By")]
121 build_tainted_by: Option<String>,
123
124 #[deb822(field = "Build-Path", deserialize_with = deserialize_pathbuf, serialize_with = serialize_pathbuf)]
125 build_path: Option<PathBuf>,
127
128 #[deb822(
129 field = "Environment",
130 deserialize_with = deserialize_env,
131 serialize_with = serialize_env
132 )]
133 environment: Option<HashMap<String, String>>,
135
136 #[deb822(field = "Installed-Build-Depends")]
137 installed_build_depends: Option<Relations>,
139}
140
141impl std::str::FromStr for Buildinfo {
142 type Err = String;
143
144 fn from_str(s: &str) -> Result<Self, Self::Err> {
145 let para: deb822_fast::Paragraph =
146 s.parse().map_err(|e: deb822_fast::Error| e.to_string())?;
147 Self::from_paragraph(¶)
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154 use std::str::FromStr;
155
156 #[test]
157 fn test_buildinfo() {
158 let input = include_str!("../../testdata/ruff.buildinfo");
159
160 let buildinfo = Buildinfo::from_str(input).unwrap();
161
162 assert_eq!(buildinfo.format, "1.0");
163 }
164
165 #[test]
166 fn test_environment_value_is_lone_quote() {
167 let line = "FOO=\"";
171 let env = super::deserialize_env(line).unwrap();
172 assert_eq!(env.get("FOO"), Some(&"\"".to_string()));
173 }
174}