[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

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
}