1use model::CgroupModelFieldId;
16use model::SingleCgroupModelFieldId;
17
18use super::*;
19
20pub struct Cgroup {
21 opts: GeneralOpt,
22 select: Option<SingleCgroupModelFieldId>,
23 fields: Vec<CgroupField>,
24}
25
26impl Cgroup {
27 pub fn new(
28 opts: &GeneralOpt,
29 select: Option<SingleCgroupModelFieldId>,
30 fields: Vec<CgroupField>,
31 ) -> Self {
32 Self {
33 opts: opts.to_owned(),
34 select,
35 fields,
36 }
37 }
38}
39
40impl Dumper for Cgroup {
41 fn dump_model(
42 &self,
43 ctx: &CommonFieldContext,
44 model: &model::Model,
45 output: &mut dyn Write,
46 round: &mut usize,
47 comma_flag: bool,
48 ) -> Result<IterExecResult> {
49 fn output_cgroup(
50 handle: &Cgroup,
51 ctx: &CommonFieldContext,
52 model: &model::CgroupModel,
53 output: &mut dyn Write,
54 round: &mut usize,
55 json: bool,
56 jval: &mut Value,
57 ) -> Result<()> {
58 let cgroup = &model.data;
59 let should_print = match (handle.select.as_ref(), handle.opts.filter.as_ref()) {
61 (Some(field_id), Some(filter)) => filter.is_match(
62 &cgroup
63 .query(field_id)
64 .map_or("?".to_owned(), |v| v.to_string()),
65 ),
66 _ => true,
67 };
68
69 if should_print {
70 match handle.opts.output_format {
71 Some(OutputFormat::Raw) | None => write!(
72 output,
73 "{}",
74 print::dump_raw_indented(
75 &handle.fields,
76 ctx,
77 cgroup,
78 *round,
79 handle.opts.repeat_title,
80 handle.opts.disable_title,
81 handle.opts.raw,
82 )
83 )?,
84 Some(OutputFormat::Csv) => write!(
85 output,
86 "{}",
87 print::dump_csv(
88 &handle.fields,
89 ctx,
90 cgroup,
91 *round,
92 handle.opts.disable_title,
93 handle.opts.raw,
94 )
95 )?,
96 Some(OutputFormat::Tsv) => write!(
97 output,
98 "{}",
99 print::dump_tsv(
100 &handle.fields,
101 ctx,
102 cgroup,
103 *round,
104 handle.opts.disable_title,
105 handle.opts.raw,
106 )
107 )?,
108 Some(OutputFormat::KeyVal) => write!(
109 output,
110 "{}",
111 print::dump_kv(&handle.fields, ctx, cgroup, handle.opts.raw)
112 )?,
113 Some(OutputFormat::Json) => {
114 *jval = print::dump_json(&handle.fields, ctx, cgroup, handle.opts.raw);
115 jval["children"] = json!([]);
116 }
117 Some(OutputFormat::OpenMetrics) => write!(
118 output,
119 "{}",
120 print::dump_openmetrics(&handle.fields, ctx, cgroup)
121 )?,
122 };
123 *round += 1;
124 }
125
126 let mut children = Vec::from_iter(&model.children);
127 if let Some(field_id) = &handle.select {
129 let field_id = CgroupModelFieldId::new(
131 Some(model::CgroupPath { path: vec![] }),
132 field_id.to_owned(),
133 );
134 if handle.opts.sort {
135 model::sort_queriables(&mut children, &field_id, false);
136 }
137
138 if handle.opts.rsort {
139 model::sort_queriables(&mut children, &field_id, false);
140 }
141
142 if (handle.opts.sort || handle.opts.rsort) && handle.opts.top != 0 {
143 children.truncate(handle.opts.top as usize);
144 }
145 }
146
147 for child_cgroup in &children {
148 let mut child = json!({});
149 output_cgroup(handle, ctx, child_cgroup, output, round, json, &mut child)?;
150 if json && child["children"].is_array() {
151 if !jval["children"].is_array() {
153 *jval = print::dump_json(&handle.fields, ctx, cgroup, handle.opts.raw);
154 jval["children"] = json!([]);
155 }
156 jval["children"].as_array_mut().unwrap().push(child);
157 }
158 }
159
160 Ok(())
161 }
162 let json = self.opts.output_format == Some(OutputFormat::Json);
163 let mut jval = json!({});
164 output_cgroup(self, ctx, &model.cgroup, output, round, json, &mut jval)?;
165 match (json, comma_flag) {
166 (true, true) => write!(output, ",{}", jval)?,
167 (true, false) => write!(output, "{}", jval)?,
168 _ => {}
169 };
170
171 Ok(IterExecResult::Success)
172 }
173}