[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"
|
||||
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]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
|
@ -127,6 +149,18 @@ dependencies = [
|
|||
"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]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
|
@ -234,4 +268,5 @@ name = "yunq"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"genco",
|
||||
]
|
||||
|
|
|
@ -5,3 +5,4 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
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 parser;
|
||||
|
||||
|
@ -27,5 +28,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
println!("{:?}", decl);
|
||||
}
|
||||
|
||||
println!("{}", codegen::generate_code(ast_parser.ast())?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -16,6 +16,19 @@ pub enum Type {
|
|||
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 {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
|
@ -50,23 +63,23 @@ impl TryFrom<&String> for Type {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct Field {
|
||||
field_type: Type,
|
||||
name: String,
|
||||
number: u64,
|
||||
repeated: bool,
|
||||
pub field_type: Type,
|
||||
pub name: String,
|
||||
pub number: u64,
|
||||
pub repeated: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Message {
|
||||
name: String,
|
||||
fields: Vec<Field>,
|
||||
pub name: String,
|
||||
pub fields: Vec<Field>,
|
||||
}
|
||||
|
||||
pub struct Method {
|
||||
name: String,
|
||||
number: u64,
|
||||
request: Option<String>,
|
||||
response: Option<String>,
|
||||
pub name: String,
|
||||
pub number: u64,
|
||||
pub request: Option<String>,
|
||||
pub response: Option<String>,
|
||||
}
|
||||
|
||||
impl Debug for Method {
|
||||
|
@ -303,7 +316,7 @@ impl<'a> Parser<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ast(&'a mut self) -> &'a Vec<Decl> {
|
||||
pub fn ast(&'a self) -> &'a Vec<Decl> {
|
||||
&self.ast
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue