dpkg_query_json/lib.rs
1//! # dpkg-query-json
2//!
3//!
4//! A crate for parsing "dpkg-query" in json.
5//!
6//! # Examples
7//!
8//!
9//! Minimum length of fields 2. Default fields `Package` `Version`. List available below.
10//!
11//! if the list of packages is empty, all are returned
12//!
13//!
14//! #### Map<String, Value>
15//! ```
16//! use dpkg_query_json::QueryFieldPackage;
17//! let fields = vec![String::from("Package"),
18//! String::from("Version"),
19//! String::from("Architecture")];
20//! let packages = vec![String::from("dpkg")];
21//! QueryFieldPackage::new(fields, packages).json(); //Map<String, Value>
22//!
23//! ```
24//!
25//!
26//! ```{"dpkg": Object({"Architecture": String("amd64"), "Version": String("1.19.7ubuntu3")})}```
27//!
28//!
29//!
30//!------------------------------------
31//!
32//!
33//!#### String
34//! ```
35//! use dpkg_query_json::QueryFieldPackage;
36//! let fields = vec![String::from("Package"),
37//! String::from("Version"),
38//! String::from("Architecture")];
39//! let packages = vec![String::from("dpkg")];
40//! QueryFieldPackage::new(fields, packages).json_string(); //String
41//!
42//! ```
43//!
44//! ```"{\"dpkg\":{\"Architecture\":\"amd64\",\"Version\":\"1.19.7ubuntu3\"}}"```
45//!
46
47
48//! # Package information fields
49//!
50//! Architecture
51//!
52//! Bugs
53//!
54//! Conffiles
55//!
56//! Config-Version
57//!
58//! Conflicts
59//!
60//! Breaks
61//!
62//! Depends
63//!
64//! Description
65//!
66//! Enhances
67//!
68//! Essential
69//!
70//! Filename
71//!
72//! Installed-Size
73//!
74//! MD5sum
75//!
76//! MSDOS-Filename
77//!
78//! Maintainer
79//!
80//! Origin
81//!
82//! Package
83//!
84//! Pre-Depends
85//!
86//! Priority
87//!
88//! Provides
89//!
90//! Recommends
91//!
92//! Replaces
93//!
94//! Revision
95//!
96//! Section
97//!
98//! Size
99//!
100//! Source
101//!
102//! Status
103//!
104//! Suggests
105//!
106//! Version
107//!
108
109
110use std::process::{Command};
111use std::io::{Error};
112use serde_json::{Value, Map, json};
113
114//#[derive(Debug)]
115pub struct QueryFieldPackage{
116 fields: Vec<String>,
117 packages: Vec<String>
118}
119
120impl QueryFieldPackage{
121 pub fn new(fields: Vec<String>, packages: Vec<String>) -> Self{
122 QueryFieldPackage{
123 fields,
124 packages
125 }
126 }
127
128 fn exec(&mut self) -> Result<String, Error> {
129
130 if self.fields.len() <= 1{
131 self.fields.clear();
132 self.fields = vec![String::from("Package"), String::from("Version")];
133 }
134
135 let mut command = String::from("dpkg-query -W");
136 if self.fields.len() > 0{
137 let mut modified_fields = Vec::with_capacity(29);
138 for str in self.fields.iter(){
139 modified_fields.push("${".to_owned() + &str + "}");
140 }
141 command.push_str(&format!(" -f '{}\t\n'", modified_fields.join("<==>")))
142 }
143
144 if self.packages.len() > 0{
145 command.push_str(&format!(" {}", self.packages.join(" ")))
146 }
147
148 match Command::new("sh")
149 .args(&["-c", command.as_str()])
150 .output(){
151 Ok(data) => {Ok(String::from_utf8_lossy(&data.stdout).to_string())}
152 Err(e) => Err(e)
153 }
154
155 }
156
157 fn parse_to_json(&mut self) -> Result<Map<String, Value>, Error> {
158 let mut data_json = Map::new();
159
160 for line in self.exec()?.split("\t\n"){
161 let mut d = Map::new();
162 let split_line = line.split("<==>").collect::<Vec<&str>>();
163 for (i,line) in split_line[1..].iter().enumerate(){
164 d.insert((self.fields[i + 1]).to_string(), json!(line));
165 }
166 &data_json.insert(split_line[0].to_string(), Value::from(d));
167 }
168
169 Ok(data_json)
170 }
171
172 pub fn json(mut self) -> Map<String, Value> {
173 self.parse_to_json().unwrap_or_else(|err|{
174 let mut x = Map::new();
175 x.insert(String::from("error"), Value::from(err.to_string()));
176 x
177 })
178 }
179
180 pub fn json_string(mut self) -> String {
181 serde_json::to_string(&self.parse_to_json().unwrap_or_else(|err|{
182 let mut x = Map::new();
183 x.insert(String::from("error"), Value::from(err.to_string()));
184 x
185 })).unwrap()
186 }
187
188}