dbus-message-parser 4.3.1

Libary to encode and decode DBus message
Documentation
use super::MatchRule;
use crate::{
    message::Message,
    value::{Bus, Value},
};

fn match_namespace<const P: char>(namespace: &str, value: &str) -> bool {
    if let Some(value) = value.strip_prefix(namespace) {
        value.starts_with(P) || value.is_empty()
    } else {
        false
    }
}

fn get_str_from_string_or_object_path(value: &Value) -> Option<&str> {
    match value {
        Value::String(string) => Some(string),
        Value::ObjectPath(object_path) => Some(object_path.as_ref()),
        _ => None,
    }
}

impl MatchRule {
    pub fn matching_rule(&self, message: &Message) -> bool {
        match self {
            MatchRule::Type(r#type) => r#type == &message.get_type(),
            MatchRule::Sender(sender_1) => {
                if let Some(sender_2) = message.get_sender() {
                    sender_1 == sender_2
                } else {
                    false
                }
            }
            MatchRule::Interface(interface_1) => {
                if let Some(interface_2) = message.get_interface() {
                    interface_1 == interface_2
                } else {
                    false
                }
            }
            MatchRule::Member(member_1) => {
                if let Some(member_2) = message.get_member() {
                    member_1 == member_2
                } else {
                    false
                }
            }
            MatchRule::Path(path_1) => {
                if let Some(path_2) = message.get_path() {
                    path_1 == path_2
                } else {
                    false
                }
            }
            MatchRule::PathNamespace(path_namespace) => {
                if let Some(path) = message.get_path() {
                    match_namespace::<'/'>(path_namespace.as_ref(), path.as_ref())
                } else {
                    false
                }
            }
            MatchRule::Destination(destination_1) => {
                if let Some(destination_2) = message.get_destination() {
                    match destination_2 {
                        Bus::WellKnownBusName(_) => false,
                        Bus::UniqueConnectionName(destination_2) => destination_1 == destination_2,
                    }
                } else {
                    false
                }
            }
            MatchRule::Arg(arg) => {
                let body = message.get_body();
                if let Some(Value::String(value)) = body.get(arg.get_index()) {
                    arg.get_value() == value
                } else {
                    false
                }
            }
            MatchRule::ArgPath(arg_path) => {
                let body = message.get_body();
                if let Some(value) = body.get(arg_path.get_index()) {
                    if let Some(string) = get_str_from_string_or_object_path(value) {
                        match_namespace::<'/'>(arg_path.get_value().as_ref(), string)
                    } else {
                        false
                    }
                } else {
                    false
                }
            }
            MatchRule::Arg0Namespace(arg0_namespace) => {
                let body = message.get_body();
                if let Some(Value::String(arg0)) = body.get(0) {
                    match_namespace::<'.'>(arg0_namespace.as_ref(), arg0)
                } else {
                    false
                }
            }
            MatchRule::Eavesdrop(_) => true,
        }
    }

    pub fn matching_rules(match_rules: &[MatchRule], message: &Message) -> bool {
        for match_rule in match_rules.iter() {
            if !match_rule.matching_rule(message) {
                return false;
            }
        }
        true
    }
}