Compare commits

..

No commits in common. "97f8a6ed23892b78ac26eecd81ec0cab2d8537b8" and "4daa5f7cdf6b6a5910a7745bffe8489226119d43" have entirely different histories.

6 changed files with 27 additions and 66 deletions

View file

@ -12,6 +12,7 @@ members = ["protogen"]
byteorder = "1.5.0"
bytes = "1.10.0"
nix = "0.29.0"
protogen = { version = "0.1.0", path = "protogen" }
sendfd = { version = "0.4", features = [ "tokio" ] }
serde = "1.0.218"
serde_derive = "1.0.218"
@ -19,6 +20,3 @@ tokio = { version = "1.43.0", features = [ "fs", "net", "rt", "rt-multi-thread",
toml = "0.8.20"
tracing = "0.1.41"
tracing-subscriber = "0.3.19"
[build-dependencies]
protogen = { version = "0.1.0", path = "protogen" }

View file

@ -1,19 +0,0 @@
use std::{env, path::Path};
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let out_file = Path::new(&out_dir).join("proto_generated.rs");
std::fs::write(&out_file, protogen::generate_from_dir("proto"))
.expect("unable to write to file");
// If rustfmt is present, run rustfmt so that the generated file is somewhat human-readable
std::process::Command::new("rustfmt")
.arg(out_file.to_str().expect("utf8 error"))
.output()
.ok();
println!("cargo::rerun-if-changed=build.rs");
println!("cargo::rerun-if-changed=proto");
println!("cargo::rerun-if-changed=protogen");
}

View file

@ -3,6 +3,9 @@ name = "protogen"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1.0.93"
quick-xml = "0.37.2"

View file

@ -1,42 +1,17 @@
use std::path::Path;
use std::path::PathBuf;
use quick_xml::events::Event;
use quote::{format_ident, quote};
use syn::Ident;
use syn::{Ident, LitStr, parse_macro_input};
use types::{WlArgType, WlInterface, WlMsg, WlMsgType};
mod types;
pub fn generate_from_dir(p: impl AsRef<Path>) -> String {
let (gen_code, (add_parsers_fn, add_object_types_fn)): (Vec<_>, (Vec<_>, Vec<_>)) =
std::fs::read_dir(p)
.expect("cannot open directory")
.filter_map(|f| f.ok())
.filter(|f| {
f.file_name()
.to_str()
.expect("utf8 encoding error")
.ends_with(".xml")
})
.map(|f| generate_from_xml_file(f.path()))
.unzip();
quote! {
#( #gen_code )*
pub fn wl_init_parsers() {
#( #add_parsers_fn(); )*
}
pub fn wl_init_known_types() {
#( #add_object_types_fn(); )*
}
}
.to_string()
}
fn generate_from_xml_file(p: impl AsRef<Path>) -> (proc_macro2::TokenStream, (Ident, Ident)) {
let file_name = p.as_ref().file_stem().expect("No file name provided");
#[proc_macro]
pub fn wayland_proto_gen(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input: LitStr = parse_macro_input!(item);
let p = PathBuf::from(input.value());
let file_name = p.file_stem().expect("No file name provided");
let xml_str = std::fs::read_to_string(&p).expect("Unable to read from file");
let mut reader = quick_xml::Reader::from_str(&xml_str);
reader.config_mut().trim_text(true);
@ -88,15 +63,13 @@ fn generate_from_xml_file(p: impl AsRef<Path>) -> (proc_macro2::TokenStream, (Id
}
}
let file_name_snake = file_name.to_str().unwrap().replace("-", "_");
// A function to add all event/request parsers to WL_EVENT_PARSERS and WL_REQUEST_PARSERS
let add_parsers_fn = format_ident!("wl_init_parsers_{}", file_name_snake);
let add_parsers_fn = format_ident!("wl_init_parsers_{}", file_name.to_str().unwrap());
// A function to add all known interfaces to the WL_KNOWN_OBJECT_TYPES map from name -> Rust type
let add_object_types_fn = format_ident!("wl_init_known_types_{}", file_name_snake);
let add_object_types_fn = format_ident!("wl_init_known_types_{}", file_name.to_str().unwrap());
let ret_code = quote! {
quote! {
#( #code )*
fn #add_parsers_fn() {
@ -107,9 +80,8 @@ fn generate_from_xml_file(p: impl AsRef<Path>) -> (proc_macro2::TokenStream, (Id
fn #add_object_types_fn() {
#( WL_KNOWN_OBJECT_TYPES.write().unwrap().insert(#known_interface_names, #known_interface_consts); )*
}
};
(ret_code, (add_parsers_fn, add_object_types_fn))
}
.into()
}
fn handle_interface(

View file

@ -113,7 +113,6 @@ impl WlMsg {
.collect();
quote! {
#[allow(unused)]
pub struct #struct_name<'a> {
_phantom: std::marker::PhantomData<&'a ()>,
#( pub #field_names: #field_types, )*
@ -146,7 +145,6 @@ impl WlMsg {
WlMsgType::#msg_type
}
#[allow(unused)]
fn try_from_msg_impl(msg: &crate::codec::WlRawMsg) -> WaylandProtocolParsingOutcome<#struct_name> {
let payload = msg.payload();
let mut pos = 0usize;

View file

@ -7,6 +7,7 @@ use std::{
};
use byteorder::ByteOrder;
use protogen::wayland_proto_gen;
use crate::{
codec::WlRawMsg,
@ -217,5 +218,13 @@ pub fn lookup_known_object_type(name: &str) -> Option<WlObjectType> {
/// The default object ID of wl_display
pub const WL_DISPLAY_OBJECT_ID: u32 = 1;
// Include code generated by build.rs
include!(concat!(env!("OUT_DIR"), "/proto_generated.rs"));
wayland_proto_gen!("proto/wayland.xml");
/// Install all available Wayland protocol parsers for use by [decode_event] and [decode_request].
pub fn wl_init_parsers() {
wl_init_parsers_wayland();
}
pub fn wl_init_known_types() {
wl_init_known_types_wayland();
}