Skip to content

Commit

Permalink
Merge pull request #1 from impiaaa/patch-1
Browse files Browse the repository at this point in the history
PerformNotificationActionRequest
  • Loading branch information
ianmarmour authored Mar 4, 2024
2 parents a093822 + 8066f08 commit 245e091
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! there are a wide variety of Attributes that can be used. Please see the attributes module
//! provided by this library for which attributes are valid when working with ANCS.
//!
pub mod action;
pub mod app;
pub mod category;
pub mod command;
Expand Down Expand Up @@ -209,4 +210,4 @@ impl AppAttribute {
},
))
}
}
}
75 changes: 75 additions & 0 deletions src/attributes/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use nom::{error::ParseError, number::complete::le_u8, IResult};

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum ActionID {
Positive = 0,
Negative = 1,
}

impl From<ActionID> for u8 {
/// Convert a `ActionID` to a `u8`:
///
/// # Examples
/// ```
/// # use ancs::attributes::action::ActionID;
/// let data: u8 = ActionID::Positive.into();
///
/// assert_eq!(0, data);
/// ```
fn from(original: ActionID) -> u8 {
match original {
ActionID::Positive => 0,
ActionID::Negative => 1,
}
}
}

impl TryFrom<u8> for ActionID {
type Error = ActionIDError;

/// Attempts to convert a `u8` to a `ActionID`
///
/// # Examples
/// ```
/// # use ancs::attributes::action::ActionID;
/// let action_id: ActionID = ActionID::try_from(0).unwrap();
///
/// assert_eq!(ActionID::Positive, action_id);
/// ```
///
fn try_from(original: u8) -> Result<Self, Self::Error> {
match original {
0 => Ok(ActionID::Positive),
1 => Ok(ActionID::Negative),
_ => Err(ActionIDError),
}
}
}

impl ActionID {
/// Attempts to parse a `ActionID` from a `&[u8]`
///
/// # Examples
/// ```
/// # use ancs::attributes::action::ActionID;
/// let data: [u8; 2] = [0, 1];
/// let (data, action_id) = ActionID::parse(&data).unwrap();
///
/// assert_eq!(ActionID::Positive, action_id);
/// ```
///
pub fn parse(i: &[u8]) -> IResult<&[u8], ActionID> {
let (i, action_id) = le_u8(i)?;

match ActionID::try_from(action_id) {
Ok(action_id) => Ok((i, action_id)),
Err(_) => Err(nom::Err::Failure(ParseError::from_error_kind(
i,
nom::error::ErrorKind::Fail,
))),
}
}
}

#[derive(Debug, Clone)]
pub struct ActionIDError;
84 changes: 80 additions & 4 deletions src/characteristics/control_point.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::attributes::action::ActionID;
use crate::attributes::app::AppAttributeID;
use crate::attributes::notification::NotificationAttributeID;
use crate::attributes::command::*;
Expand Down Expand Up @@ -115,8 +116,6 @@ impl GetNotificationAttributesRequest {
))
)(i)?;

println!("{:?}", attribute_ids);

Ok((
i,
GetNotificationAttributesRequest {
Expand Down Expand Up @@ -204,8 +203,6 @@ impl GetAppAttributesRequest {
AppAttributeID::parse
)(i)?;

println!("{:?}", attribute_ids);

Ok((
i,
GetAppAttributesRequest {
Expand All @@ -216,3 +213,82 @@ impl GetAppAttributesRequest {
))
}
}

pub struct PerformNotificationActionRequest {
pub command_id: CommandID,
pub notification_uid: u32,
pub action_id: ActionID,
}

impl From<PerformNotificationActionRequest> for Vec<u8> {
/// Converts a `PerformNotificationActionRequest` to a `Vec<u8>`
///
/// # Examples
/// ```
/// # use ancs::attributes::command::CommandID;
/// # use ancs::attributes::action::ActionID;
/// # use ancs::characteristics::control_point::PerformNotificationActionRequest;
/// let notification: PerformNotificationActionRequest = PerformNotificationActionRequest {
/// command_id: CommandID::PerformNotificationAction,
/// notification_uid: 4294967295_u32,
/// action_id: ActionID::Positive,
/// };
///
/// let data: Vec<u8> = notification.into();
/// let expected_data: Vec<u8> = vec![2, 255, 255, 255, 255, 0];
///
/// assert_eq!(data, expected_data)
/// ```
fn from(original: PerformNotificationActionRequest) -> Vec<u8> {
let mut vec: Vec<u8> = Vec::new();

// Convert all attributes to bytes
let command_id: u8 = original.command_id.into();
let notification_uid: [u8; 4] = original.notification_uid.to_le_bytes();
let action_id: u8 = original.action_id.into();

vec.push(command_id);
vec.extend(notification_uid);
vec.push(action_id);

return vec;
}
}

impl PerformNotificationActionRequest {
/// Attempts to parse a `PerformNotificationActionRequest` from a `&[u8]`
///
/// # Examples
/// ```
/// # use ancs::attributes::command::CommandID;
/// # use ancs::attributes::action::ActionID;
/// # use ancs::characteristics::control_point::PerformNotificationActionRequest;
/// let data: Vec<u8> = vec![
/// 2,
/// 255,
/// 255,
/// 255,
/// 255,
/// 0,
/// ];
/// let (data, notification) = PerformNotificationActionRequest::parse(&data).unwrap();
///
/// assert_eq!(notification.command_id, CommandID::PerformNotificationAction);
/// assert_eq!(notification.notification_uid, 4294967295_u32);
/// assert_eq!(notification.action_id, ActionID::Positive);
/// ```
pub fn parse(i: &[u8]) -> IResult<&[u8], PerformNotificationActionRequest> {
let (i, command_id) = CommandID::parse(i)?;
let (i, notification_uid) = le_u32(i)?;
let (i, action_id) = ActionID::parse(i)?;

Ok((
i,
PerformNotificationActionRequest {
command_id: command_id,
notification_uid: notification_uid,
action_id: action_id,
},
))
}
}

0 comments on commit 245e091

Please sign in to comment.