Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Volkalex28 committed Jun 16, 2023
1 parent 1f31565 commit 7b93191
Show file tree
Hide file tree
Showing 34 changed files with 4,524 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ Cargo.lock

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

/.vscode
main.rs
29 changes: 29 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "varuemb"
version = "0.1.0"
edition = "2021"
rust-version = "1.68"
authors = ["Volkalex28 <[email protected]>"]
description = """Toolchain for easy creation of asynchronous embedded applications on rust-lang"""
license = "MIT"
homepage = "https://github.com/Volkalex28/varu-emb#readme"
repository = "https://github.com/Volkalex28/varu-emb"
readme = "README.md"
categiries = ["asynchronous", "data-structures", "embedded"]
keywords = ["channels", "embassy", "async", "notification", "rpc"]
include = [
"/src",
"/utils",
"/notifier",
"/README.md",
"/LICENSE",
]

[dependencies.varuemb-utils]
path = "utils/"

[dependencies.varuemb-notifier]
path = "notifier/"

[workspace]
members = ["utils", "notifier"]
30 changes: 30 additions & 0 deletions notifier/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "varuemb-notifier"
version = "0.1.0"
edition = "2021"
rust-version = "1.68"
authors = ["Volkalex28 <[email protected]>"]
description = """
varuemb-notifier allows to create and configure synchronous and asynchronous pub-sub interface
and asynchronous rpc interface for services in embedded applications
"""
license = "MIT"
readme = "README.md"
categiries = ["asynchronous", "data-structures", "embedded"]
keywords = ["channels", "embassy", "async", "notification", "rpc"]
include = [
"/src",
"/proc",
"/README.md",
]


[dependencies]
anyhow = "1.0.71"
embassy-sync = { version = "0.2.0" }
embassy-time = { version = "0.1.1"}
futures-util = "0.3.28"
heapless = "0.7.16"
log = "0.4.17"
varuemb-notifier-proc = { path = "proc" }
varuemb-utils = { path = "../utils" }
6 changes: 6 additions & 0 deletions notifier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# valex-notifier

valex-notifier allows to create and configure synchronous and asynchronous pub-sub interface
and asynchronous rpc interface for services in embedded applications

(Soon to get Git tags, docs, etc.)
17 changes: 17 additions & 0 deletions notifier/proc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "varuemb-notifier-proc"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
heck = "0.4"
linked-hash-map = "0.5.6"
syn = { version = "2.0.16", features = ["full", "extra-traits" ] }
proc-macro2 = "1.0"
quote = "1.0"
varuemb-utils = { path = "../../utils" }

[lib]
proc-macro = true
76 changes: 76 additions & 0 deletions notifier/proc/src/event/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use proc_macro2::Ident;
use quote::{quote, ToTokens};
use syn::{spanned::Spanned, DeriveInput, Error, Path};
use varuemb_utils::proc_meta_parser::Parser;

pub struct Event<'a> {
meta: &'a super::Meta,
ident: &'a Ident,
notif: Path,
service: Option<Path>,
is_mixer: bool,
}

impl<'a> Event<'a> {
pub(crate) fn new(input: &'a DeriveInput, meta: &'a super::Meta) -> Result<Self, Error> {
let mut attrs = input.attrs.iter().filter_map(|a| {
if a.path().is_ident("notifier_event") {
Some((a, false))
} else if a.path().is_ident("notifier_mixer") {
Some((a, true))
} else {
None
}
});
let Some((attr, is_mixer)) = attrs.next() else {
return Err(Error::new(input.span(), "Attribute \"notifier_event\" or \"notifier_mixer\" not found"));
};
if let Some((attr, _)) = attrs.next() {
return Err(Error::new(
attr.span(),
"Supports only one of \"notifier_event\" or \"notifier_mixer\" attributes",
));
}

let mut parser = Parser::new(["notifier", "service"], attr.span());
attr.parse_nested_meta(|meta| parser.parse(meta))?;

Ok(Self {
meta,
is_mixer,
ident: &input.ident,
notif: parser.get("notifier")?,
service: match parser.get("service") {
Ok(s) => Some(s),
Err(_) if is_mixer => None,
Err(err) => return Err(err),
},
})
}
}

impl<'a> ToTokens for Event<'a> {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let _crate = &self.meta.crate_ident;
let Self {
ident,
notif,
service,
is_mixer,
..
} = self;

let out = if *is_mixer {
quote! {
impl #_crate ::pubsub::mixer::Mixer<#notif> for #ident {}
}
} else {
quote! {
impl #_crate ::event::traits::Event<#notif> for #ident {
type Service = #service;
}
}
};
tokens.extend(out)
}
}
83 changes: 83 additions & 0 deletions notifier/proc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#![feature(box_patterns)]
#![feature(iterator_try_collect)]

use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens};
use syn::Error;

mod event;
mod notifier;
mod rpc;
mod service;

#[derive(Debug)]
struct Meta {
crate_ident: TokenStream2,
}
impl Default for Meta {
fn default() -> Self {
Self {
crate_ident: quote!(::varuemb_notifier),
}
}
}

/// This is a procedural macro that provides auto-generation of the "Notifier" structure
/// for storing and managing communication channels between services
#[proc_macro_attribute]
pub fn notifier(attrs: TokenStream, input: TokenStream) -> TokenStream {
(|| -> Result<TokenStream2, Error> {
let meta = Meta::default();
let input = syn::parse(input)?;
let notif = notifier::Notifier::new(attrs.into(), &input, &meta)?;
Ok(notif.to_token_stream())
})()
.unwrap_or_else(|err| err.to_compile_error())
.into()
}

#[proc_macro_derive(
Service,
attributes(
notifier_service,
notifier_publisher,
notifier_subscriber,
notifier_rpc_subscriber
)
)]
pub fn service_derive(input: TokenStream) -> TokenStream {
(|| -> Result<TokenStream2, Error> {
let meta = Meta::default();
let input = syn::parse(input)?;
let service = service::Service::new(&input, &meta)?;
Ok(service.to_token_stream())
})()
.unwrap_or_else(|err| err.to_compile_error())
.into()
}

#[proc_macro_attribute]
pub fn rpc_handlers(attrs: TokenStream, input: TokenStream) -> TokenStream {
(|attrs: TokenStream2| -> Result<TokenStream2, Error> {
let meta = Meta::default();
let attr = syn::parse_quote!(#[rpc_handlers(#attrs)]);
let input = syn::parse(input)?;
let rpc = rpc::Rpc::new(&attr, input, &meta)?;
Ok(rpc.to_token_stream())
})(attrs.into())
.unwrap_or_else(|err| err.to_compile_error())
.into()
}

#[proc_macro_derive(Event, attributes(notifier_event, notifier_mixer))]
pub fn event_derive(input: TokenStream) -> TokenStream {
(|| -> Result<TokenStream2, Error> {
let meta = Meta::default();
let input = syn::parse(input)?;
let event = event::Event::new(&input, &meta)?;
Ok(event.to_token_stream())
})()
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
Loading

0 comments on commit 7b93191

Please sign in to comment.