[Yunq] Codegen example for yunq implementation.
This commit is contained in:
parent
12fb84cfad
commit
d6833be0ad
|
@ -97,6 +97,28 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "genco"
|
||||||
|
version = "0.17.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "afac3cbb14db69ac9fef9cdb60d8a87e39a7a527f85a81a923436efa40ad42c6"
|
||||||
|
dependencies = [
|
||||||
|
"genco-macros",
|
||||||
|
"relative-path",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "genco-macros"
|
||||||
|
version = "0.17.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -127,6 +149,18 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "relative-path"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
|
@ -234,4 +268,5 @@ name = "yunq"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"genco",
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,3 +5,4 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.7", features = ["derive"] }
|
clap = { version = "4.5.7", features = ["derive"] }
|
||||||
|
genco = { version = "0.17.9" }
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
use crate::parser::{Decl, Field, Interface, Message};
|
||||||
|
use genco::fmt;
|
||||||
|
use genco::fmt::FmtWriter;
|
||||||
|
use genco::prelude::quote_fn;
|
||||||
|
use genco::prelude::quote_in;
|
||||||
|
use genco::prelude::rust;
|
||||||
|
use genco::prelude::FormatInto;
|
||||||
|
use genco::prelude::Rust;
|
||||||
|
|
||||||
|
pub fn generate_field_def<'a>(field: &'a Field) -> impl FormatInto<Rust> + 'a {
|
||||||
|
quote_fn!(
|
||||||
|
$(field.name.clone()): $(field.field_type.rust_type()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_message_code<'a>(message: &'a Message) -> impl FormatInto<Rust> + 'a {
|
||||||
|
quote_fn!(
|
||||||
|
struct $(&message.name) {$['\r']
|
||||||
|
$(for field in &message.fields =>
|
||||||
|
$[' ']$(generate_field_def(field))$['\r']
|
||||||
|
)}$['\n']
|
||||||
|
|
||||||
|
impl $(&message.name) {$['\r']
|
||||||
|
jjj
|
||||||
|
|
||||||
|
}$['\n']
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_code(ast: &Vec<Decl>) -> Result<String, std::fmt::Error> {
|
||||||
|
let mut tokens = rust::Tokens::new();
|
||||||
|
|
||||||
|
for decl in ast {
|
||||||
|
match decl {
|
||||||
|
Decl::Message(message) => quote_in!(tokens => $(generate_message_code(message))),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut w = FmtWriter::new(String::new());
|
||||||
|
|
||||||
|
let fmt = fmt::Config::from_lang::<Rust>()
|
||||||
|
.with_indentation(fmt::Indentation::Space(4))
|
||||||
|
.with_newline("\n");
|
||||||
|
|
||||||
|
let config = rust::Config::default()
|
||||||
|
// Prettier imports and use.
|
||||||
|
.with_default_import(rust::ImportMode::Qualified);
|
||||||
|
|
||||||
|
tokens.format_file(&mut w.as_formatter(&fmt), &config)?;
|
||||||
|
|
||||||
|
Ok(w.into_inner())
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod codegen;
|
||||||
mod lexer;
|
mod lexer;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
|
@ -27,5 +28,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
println!("{:?}", decl);
|
println!("{:?}", decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("{}", codegen::generate_code(ast_parser.ast())?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,19 @@ pub enum Type {
|
||||||
Message(String),
|
Message(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type {
|
||||||
|
pub fn rust_type(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Type::U64 => "u64",
|
||||||
|
Type::I64 => "i64",
|
||||||
|
Type::String => "String",
|
||||||
|
Type::Bytes => "Vec<u8>",
|
||||||
|
Type::Capability => "u64",
|
||||||
|
Type::Message(s) => s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Type {
|
impl Display for Type {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
|
@ -50,23 +63,23 @@ impl TryFrom<&String> for Type {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
field_type: Type,
|
pub field_type: Type,
|
||||||
name: String,
|
pub name: String,
|
||||||
number: u64,
|
pub number: u64,
|
||||||
repeated: bool,
|
pub repeated: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
name: String,
|
pub name: String,
|
||||||
fields: Vec<Field>,
|
pub fields: Vec<Field>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Method {
|
pub struct Method {
|
||||||
name: String,
|
pub name: String,
|
||||||
number: u64,
|
pub number: u64,
|
||||||
request: Option<String>,
|
pub request: Option<String>,
|
||||||
response: Option<String>,
|
pub response: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Method {
|
impl Debug for Method {
|
||||||
|
@ -303,7 +316,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ast(&'a mut self) -> &'a Vec<Decl> {
|
pub fn ast(&'a self) -> &'a Vec<Decl> {
|
||||||
&self.ast
|
&self.ast
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue