1use std::{collections::HashMap, fmt::Debug};
3
4use serde::{Deserialize, Serialize};
5use serde_json_any_key::any_key_map;
6
7pub mod linux;
8pub mod rust;
9
10#[derive(Clone, Debug, Default, Deserialize, Serialize)]
12#[serde(default)]
13pub struct MapState {
14 pub id: u32,
16 #[serde(rename = "type")]
18 pub _type: String,
19 is_static: bool,
21 pub bytes_key: u32,
23 pub bytes_value: u32,
25 #[serde(with = "any_key_map")]
26 pub data: HashMap<Vec<u8>, Vec<Vec<u8>>>,
27}
28
29impl PartialEq for MapState {
30 fn eq(&self, other: &Self) -> bool {
31 if self.id != other.id
32 || self._type != other._type
33 || self.bytes_key != other.bytes_key
34 || self.bytes_value != other.bytes_value
35 || (self.is_static && self.data != other.data)
36 {
37 return false;
38 }
39 true
40 }
41}
42
43#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
45#[serde(default)]
46pub struct PinState {
47 pub dir: String,
49 pub pins: HashMap<String, u64>,
51}
52
53#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
55#[serde(default)]
56pub struct BPFState {
57 pub pid: u32,
59 pub maps: HashMap<String, MapState>,
61 pub pins: PinState,
63}
64
65impl BPFState {
66 pub fn diff(&self, other: &BPFState) {
68 if self.pid != other.pid {
70 println!("self pid: {} other pid: {}", self.pid, other.pid);
71 }
72 for (name, data) in &self.maps {
74 match other.maps.get(name) {
75 None => println!("other did not contain map: {name}"),
76 Some(other_data) => {
77 if data != other_data {
78 println!("map '{name}' is different.")
79 }
80 for (k, v) in &data.data {
81 match other_data.data.get(k) {
82 None => {
83 println!("other does not have\nkey: {k:?}\nvalue:{v:?}")
84 }
85 Some(other_v) => {
86 if v != other_v {
87 println!(
88 "different values for key:\n{k:?}\nself: {v:?}\nother: {other_v:?}"
89 )
90 }
91 }
92 }
93 }
94 }
95 }
96 }
97 if self.pins.dir != other.pins.dir {
99 println!(
100 "pin dir does not match: self {}, other: {}",
101 self.pins.dir, other.pins.dir
102 )
103 }
104 for (name, data) in &self.pins.pins {
105 match other.pins.pins.get(name) {
106 None => println!("other does not have pin: {name}"),
107 Some(other_data) => {
108 if data != other_data {
109 println!(
110 "pin data does not match for pin {name}\nself: {data}\nother: {other_data}"
111 )
112 }
113 }
114 }
115 }
116 }
117}