summaryrefslogtreecommitdiff
path: root/nrf-softdevice-macro
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2020-11-09 18:22:54 +0100
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2020-11-09 18:22:54 +0100
commit6a33fc8bb70a248c904c16f9b4eb594be7eb9815 (patch)
tree412cec470915e7738a7b5b64b8068b8bb91dd8ac /nrf-softdevice-macro
parent81b795229bed915247b2f44fedb6d09335d2ec15 (diff)
downloadnrf-softdevice-6a33fc8bb70a248c904c16f9b4eb594be7eb9815.zip
Add uuid handling in gatt_server proc macro.
Diffstat (limited to 'nrf-softdevice-macro')
-rw-r--r--nrf-softdevice-macro/Cargo.toml1
-rw-r--r--nrf-softdevice-macro/src/lib.rs21
-rw-r--r--nrf-softdevice-macro/src/uuid.rs43
3 files changed, 58 insertions, 7 deletions
diff --git a/nrf-softdevice-macro/Cargo.toml b/nrf-softdevice-macro/Cargo.toml
index 81ddcb8..81bbba8 100644
--- a/nrf-softdevice-macro/Cargo.toml
+++ b/nrf-softdevice-macro/Cargo.toml
@@ -10,6 +10,7 @@ quote = "1.0.7"
darling = "0.10.2"
proc-macro2 = "1.0.18"
Inflector = "0.11.4"
+uuid = "0.8.1"
[lib]
proc-macro = true
diff --git a/nrf-softdevice-macro/src/lib.rs b/nrf-softdevice-macro/src/lib.rs
index 158679b..4e6a0fd 100644
--- a/nrf-softdevice-macro/src/lib.rs
+++ b/nrf-softdevice-macro/src/lib.rs
@@ -2,20 +2,25 @@
extern crate proc_macro;
+use core::str::FromStr;
use darling::FromMeta;
-use proc_macro::{TokenStream};
-use proc_macro2::{TokenStream as TokenStream2};
+use proc_macro::TokenStream;
+use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};
use std::iter::FromIterator;
use syn::spanned::Spanned;
+mod uuid;
+
+use crate::uuid::Uuid;
+
#[derive(Debug, FromMeta)]
struct ServerArgs {
- uuid: String,
+ uuid: Uuid,
}
#[derive(Debug, FromMeta)]
struct CharacteristicArgs {
- uuid: String,
+ uuid: Uuid,
#[darling(default)]
read: bool,
#[darling(default)]
@@ -38,7 +43,7 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
let args = syn::parse_macro_input!(args as syn::AttributeArgs);
let mut struc = syn::parse_macro_input!(item as syn::ItemStruct);
- let _args = match ServerArgs::from_list(&args) {
+ let args = match ServerArgs::from_list(&args) {
Ok(v) => v,
Err(e) => {
return e.write_errors().into();
@@ -115,6 +120,7 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
let set_fn = format_ident!("{}_set", ch.name);
let notify_fn = format_ident!("{}_notify", ch.name);
+ let uuid = ch.args.uuid;
let read = ch.args.read;
let write = ch.args.write;
let notify = ch.args.notify;
@@ -132,7 +138,7 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
code_register_chars.extend(quote!(
let #char_name = register_char(
Characteristic {
- uuid: GATT_BAS_BATTERY_LEVEL_CHAR_UUID,
+ uuid: #uuid,
can_read: #read,
can_write: #write,
can_notify: #notify,
@@ -220,6 +226,7 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
//panic!();
}
+ let uuid = args.uuid;
struct_fields.named = syn::punctuated::Punctuated::from_iter(fields);
let result = quote! {
@@ -233,7 +240,7 @@ pub fn gatt_server(args: TokenStream, item: TokenStream) -> TokenStream {
type Event = #event_enum_name;
fn uuid() -> Uuid {
- GATT_BAS_SVC_UUID
+ #uuid
}
fn register<F>(service_handle: u16, mut register_char: F) -> Result<Self, RegisterError>
diff --git a/nrf-softdevice-macro/src/uuid.rs b/nrf-softdevice-macro/src/uuid.rs
new file mode 100644
index 0000000..950c3fd
--- /dev/null
+++ b/nrf-softdevice-macro/src/uuid.rs
@@ -0,0 +1,43 @@
+use core::str::FromStr;
+use darling::FromMeta;
+use proc_macro2::TokenStream as TokenStream2;
+use quote::quote;
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub enum Uuid {
+ Uuid16(u16),
+ Uuid128([u8; 16]),
+}
+
+impl FromMeta for Uuid {
+ fn from_string(value: &str) -> darling::Result<Self> {
+ if let Ok(u) = uuid::Uuid::from_str(value) {
+ return Ok(Uuid::Uuid128(*u.as_bytes()));
+ }
+
+ if value.len() == 4 {
+ if let Ok(u) = u16::from_str_radix(value, 16) {
+ return Ok(Uuid::Uuid16(u));
+ }
+ }
+
+ Err(darling::Error::custom(
+ "Invalid UUID (must be a 16-bit or 128-bit UUID)",
+ ))
+ }
+}
+
+impl quote::ToTokens for Uuid {
+ fn to_tokens(&self, tokens: &mut TokenStream2) {
+ match self {
+ Uuid::Uuid16(u) => tokens.extend(quote!(::nrf_softdevice::ble::Uuid::new_16(#u))),
+ Uuid::Uuid128(u) => {
+ let mut s = TokenStream2::new();
+ for b in u {
+ s.extend(quote!(#b,))
+ }
+ tokens.extend(quote!(::nrf_softdevice::ble::Uuid::new_128(&[#s])));
+ }
+ }
+ }
+}