dbus_message_parser/match_rule/
matching.rs1use super::MatchRule;
2use crate::{
3 message::Message,
4 value::{Bus, Value},
5};
6
7fn match_namespace<const P: char>(namespace: &str, value: &str) -> bool {
8 if let Some(value) = value.strip_prefix(namespace) {
9 value.starts_with(P) || value.is_empty()
10 } else {
11 false
12 }
13}
14
15fn get_str_from_string_or_object_path(value: &Value) -> Option<&str> {
16 match value {
17 Value::String(string) => Some(string),
18 Value::ObjectPath(object_path) => Some(object_path.as_ref()),
19 _ => None,
20 }
21}
22
23impl MatchRule {
24 pub fn matching_rule(&self, message: &Message) -> bool {
25 match self {
26 MatchRule::Type(r#type) => r#type == &message.get_type(),
27 MatchRule::Sender(sender_1) => {
28 if let Some(sender_2) = message.get_sender() {
29 sender_1 == sender_2
30 } else {
31 false
32 }
33 }
34 MatchRule::Interface(interface_1) => {
35 if let Some(interface_2) = message.get_interface() {
36 interface_1 == interface_2
37 } else {
38 false
39 }
40 }
41 MatchRule::Member(member_1) => {
42 if let Some(member_2) = message.get_member() {
43 member_1 == member_2
44 } else {
45 false
46 }
47 }
48 MatchRule::Path(path_1) => {
49 if let Some(path_2) = message.get_path() {
50 path_1 == path_2
51 } else {
52 false
53 }
54 }
55 MatchRule::PathNamespace(path_namespace) => {
56 if let Some(path) = message.get_path() {
57 match_namespace::<'/'>(path_namespace.as_ref(), path.as_ref())
58 } else {
59 false
60 }
61 }
62 MatchRule::Destination(destination_1) => {
63 if let Some(destination_2) = message.get_destination() {
64 match destination_2 {
65 Bus::WellKnownBusName(_) => false,
66 Bus::UniqueConnectionName(destination_2) => destination_1 == destination_2,
67 }
68 } else {
69 false
70 }
71 }
72 MatchRule::Arg(arg) => {
73 let body = message.get_body();
74 if let Some(Value::String(value)) = body.get(arg.get_index()) {
75 arg.get_value() == value
76 } else {
77 false
78 }
79 }
80 MatchRule::ArgPath(arg_path) => {
81 let body = message.get_body();
82 if let Some(value) = body.get(arg_path.get_index()) {
83 if let Some(string) = get_str_from_string_or_object_path(value) {
84 match_namespace::<'/'>(arg_path.get_value().as_ref(), string)
85 } else {
86 false
87 }
88 } else {
89 false
90 }
91 }
92 MatchRule::Arg0Namespace(arg0_namespace) => {
93 let body = message.get_body();
94 if let Some(Value::String(arg0)) = body.get(0) {
95 match_namespace::<'.'>(arg0_namespace.as_ref(), arg0)
96 } else {
97 false
98 }
99 }
100 MatchRule::Eavesdrop(_) => true,
101 }
102 }
103
104 pub fn matching_rules(match_rules: &[MatchRule], message: &Message) -> bool {
105 for match_rule in match_rules.iter() {
106 if !match_rule.matching_rule(message) {
107 return false;
108 }
109 }
110 true
111 }
112}