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}