win_sid_macros/
lib.rs

1#![forbid(unsafe_code)]
2#![deny(clippy::unwrap_used)]
3
4use std::str::FromStr;
5
6use proc_macro2::TokenStream;
7use proc_macro2_diagnostics::{Diagnostic, Level};
8use quote::quote;
9use syn::{parse_macro_input, LitStr};
10use win_sid_core::SecurityIdentifier;
11
12extern crate proc_macro;
13
14/// The sid macro will parse/validate a SID at compile time.
15/// 
16/// Only supports SIDs that are const constructable - that is, SIDs with six or less sub-authorities
17#[proc_macro]
18pub fn sid(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
19    let constant_value = parse_macro_input!(input as LitStr);
20    match sid_inner(constant_value) {
21        Ok(tokens) => tokens.into(),
22        Err(diag) => diag.emit_as_expr_tokens().into(),
23    }
24}
25
26fn sid_inner(constant_value: LitStr) -> Result<TokenStream, Diagnostic> {
27    let sid = SecurityIdentifier::from_str(&constant_value.value()).map_err(|err| Diagnostic::new(Level::Error, err.to_string()))?;
28    let identifier_authorities: u64 = sid.get_identifier_authority().to_owned().into();
29    let sub_authorities = sid.get_identifier_sub_authority();
30    Ok(quote!(
31        win_sid::SecurityIdentifier::new_const((#identifier_authorities as u64), [#( #sub_authorities ),*])
32    ))
33}