[Yunq] Codegen example for yunq implementation.

This commit is contained in:
Drew Galbraith 2024-06-11 15:11:56 -07:00
parent 12fb84cfad
commit d6833be0ad
5 changed files with 116 additions and 11 deletions

35
yunq/rust/Cargo.lock generated
View File

@ -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",
]

View File

@ -5,3 +5,4 @@ edition = "2021"
[dependencies]
clap = { version = "4.5.7", features = ["derive"] }
genco = { version = "0.17.9" }

53
yunq/rust/src/codegen.rs Normal file
View File

@ -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())
}

View File

@ -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(())
}

View File

@ -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
}