Skip to content

Commit

Permalink
api cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtbuilds committed Feb 15, 2024
1 parent 195713f commit 363882a
Show file tree
Hide file tree
Showing 19 changed files with 257 additions and 228 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions libninja/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use tracing::debug;

use ::mir::{File, Import, Visibility};
use codegen::ToRustType;
use format::format_code;
use mir_rust::format_code;
use hir::{AuthStrategy, HirSpec, Location, Oauth2Auth, Parameter, qualified_env_var};
use ln_core::{copy_builtin_files, copy_builtin_templates, create_context, get_template_file, prepare_templates};
use ln_core::fs;
Expand Down Expand Up @@ -206,12 +206,12 @@ fn write_file_with_template(mut file: File<TokenStream>, template: Option<String
#doc
#(#imports)*
};
let mut code = format_code(pre)?;
let mut code = format_code(pre);
code.push('\n');
code += template.trim();
code.push('\n');
let after = file.to_rust_code();
code += &format_code(after)?;
code += &format_code(after);
fs::write_file(path, &code)
}

Expand Down Expand Up @@ -480,6 +480,6 @@ fn write_serde_module_if_needed(extras: &Extras, dest: &Path) -> Result<()> {
#date_as_int
#int_as_str
};
let code = format_code(code).unwrap();
let code = format_code(code);
fs::write_file(&src_path, &code)
}
4 changes: 2 additions & 2 deletions libninja/src/rust/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ pub fn struct_Client(spec: &HirSpec, opt: &PackageConfig) -> Class<TokenStream>

let mut instance_fields = vec![
Field {
name: "client".to_string(),
name: Ident::new("client"),
ty: quote!(Cow<'static, httpclient::Client>),
..Field::default()
}
];
if spec.has_security() {
instance_fields.push(Field {
name: "authentication".to_string(),
name: Ident::new("authentication"),
ty: quote!(#auth_struct_name),
..Field::default()
});
Expand Down
4 changes: 2 additions & 2 deletions libninja/src/rust/codegen/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use mir::{File, Import, Ty};
use crate::PackageConfig;
use crate::rust::codegen::{ToRustCode, ToRustType};
use crate::rust::codegen::ToRustIdent;
use crate::rust::format::format_code;
use mir_rust::format_code;

pub trait ToRustExample {
fn to_rust_example(&self, spec: &HirSpec) -> anyhow::Result<TokenStream>;
Expand Down Expand Up @@ -67,7 +67,7 @@ pub fn generate_example(operation: &Operation, opt: &PackageConfig, spec: &HirSp
..File::default()
};
let code = example.to_rust_code();
format_code(code)
Ok(format_code(code))
}

pub fn to_rust_example_value(ty: &Ty, name: &str, spec: &HirSpec, use_ref_value: bool) -> anyhow::Result<TokenStream> {
Expand Down
24 changes: 2 additions & 22 deletions libninja/src/rust/format.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
use anyhow::Result;
use proc_macro2::TokenStream;
use std::fs::File;
use std::io::Write;

pub fn format_code(code: TokenStream) -> Result<String> {
let code = code.to_string();
let syntax_tree = match syn::parse_file(&code) {
Ok(syntax_tree) => syntax_tree,
Err(e) => {
println!("{}", code);
return Err(anyhow::anyhow!(
"Failed to parse generated code: {}",
e
))
}
};
let mut code = prettyplease::unparse(&syntax_tree);
if code.ends_with('\n') {
code.pop();
}
Ok(code)
}

#[cfg(test)]
mod tests {
use super::*;
use proc_macro2::TokenStream;
use quote::quote;
use mir_rust::format_code;

fn codegen_example() -> TokenStream {
quote! {
Expand All @@ -41,7 +21,7 @@ mod tests {
#[test]
fn test_codegen() {
let code = codegen_example();
let code = format_code(code).unwrap();
let code = format_code(code);
assert_eq!(
code,
r#"
Expand Down
4 changes: 2 additions & 2 deletions libninja/src/rust/io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::Path;
use proc_macro2::TokenStream;
use ln_core::fs;
use crate::rust::format::format_code;
use mir_rust::format_code;
use mir_rust::ToRustCode;

pub fn write_rust_file_to_path(path: &Path, file: mir::File<TokenStream>) -> anyhow::Result<()> {
Expand All @@ -14,7 +14,7 @@ pub fn write_rust_code_to_path(path: &Path, code: TokenStream) -> anyhow::Result
}

pub fn write_rust_to_path(path: &Path, code: TokenStream, template: &str) -> anyhow::Result<()> {
let code = format_code(code)?;
let code = format_code(code);
let mut f = fs::open(path)?;
let mut s = template.to_string();
if !s.is_empty() && !s.ends_with('\n') {
Expand Down
6 changes: 3 additions & 3 deletions libninja/src/rust/lower_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl StructExt for Struct {
_ => {}
}
Field {
name: name.clone(),
name: name.to_rust_ident(),
ty,
vis: Visibility::Public,
decorators,
Expand Down Expand Up @@ -336,7 +336,7 @@ mod tests {
use hir::HirField;
use mir::Ty;

use crate::rust::format::format_code;
use mir_rust::format_code;

use super::*;

Expand All @@ -352,7 +352,7 @@ mod tests {
docs: None,
};
let code = create_newtype_struct(&schema, &HirSpec::default());
let code = format_code(code).unwrap();
let code = format_code(code);
assert_eq!(&code, "
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct NewType(pub String);
Expand Down
2 changes: 1 addition & 1 deletion libninja/src/rust/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub fn build_struct_fields(
tok = quote! { Option<#tok> }
}
Field {
name: input.name.clone(),
name: input.name.to_rust_ident(),
ty: tok,
vis: Visibility::Public,
..Field::default()
Expand Down
2 changes: 1 addition & 1 deletion libninja/tests/all_of/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fn record_for_schema(name: &str, schema: &str, spec: &OpenAPI) -> Record {
fn formatted_code(record: Record, spec: &HirSpec) -> String {
let config = ConfigFlags::default();
let code = libninja::rust::lower_hir::create_struct(&record, &config, spec);
libninja::rust::format::format_code(code).unwrap()
mir_rust::format_code(code)
}

#[test]
Expand Down
73 changes: 73 additions & 0 deletions mir/src/class.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::fmt::{Debug, Formatter};
use crate::{Doc, Function, Ident, Visibility};

pub struct Class<T> {
pub name: Ident,
pub doc: Option<Doc>,
/// `code` is for Python, where we need code like this:
/// class Account(BaseModel):
/// class Config:
/// this_is_a_config_for_pydantic = True
pub code: Option<String>,
pub instance_fields: Vec<Field<T>>,
pub static_fields: Vec<Field<T>>,
pub constructors: Vec<Function<T>>,
/// Use `class_methods` in Rust.
pub class_methods: Vec<Function<T>>,
pub static_methods: Vec<Function<T>>,
pub public: bool,

pub lifetimes: Vec<String>,
pub decorators: Vec<T>,
pub superclasses: Vec<T>,
}

#[derive(Debug, Default)]
pub struct Field<T> {
pub name: Ident,
pub ty: T,
pub default: Option<T>,
pub vis: Visibility,
pub doc: Option<Doc>,
pub optional: bool,
pub decorators: Vec<T>,
}


impl Debug for Class<String> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let public = self.public;
write!(f, "Class {{ name: {name:?}, \
doc: {doc:?}, \
instance_fields: todo!, \
static_fields: todo!, \
constructors: todo!, \
class_methods: todo!, \
static_methods: todo!, \
public: {public}, \
lifetimes: todo!, \
superclasses: todo! }}",
name = self.name,
doc = self.doc,
)
}
}

impl<T> Default for Class<T> {
fn default() -> Self {
Self {
name: Ident("".to_string()),
code: None,
doc: None,
instance_fields: vec![],
static_fields: vec![],
constructors: vec![],
class_methods: vec![],
static_methods: vec![],
public: false,
lifetimes: vec![],
decorators: vec![],
superclasses: vec![],
}
}
}
6 changes: 6 additions & 0 deletions mir/src/doc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#[derive(Debug, Clone)]
pub struct Doc(pub String);

impl Into<Doc> for &str {
fn into(self) -> Doc {
Doc(self.to_string())
}
}

pub enum DocFormat {
Markdown,
Rst,
Expand Down
2 changes: 1 addition & 1 deletion mir/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl<T> Default for Function<T>
{
fn default() -> Self {
Self {
name: Ident::new(""),
name: Ident("".to_string()),
args: vec![],
ret: T::default(),
body: T::default(),
Expand Down
23 changes: 23 additions & 0 deletions mir/src/ident.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::fmt::Formatter;

/// Localized string
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
pub struct Ident(pub String);

impl Ident {
pub fn new(s: &'static str) -> Self {
Ident(s.into())
}
}

impl std::fmt::Display for Ident {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

impl PartialEq<str> for Ident {
fn eq(&self, other: &str) -> bool {
self.0 == *other
}
}
51 changes: 51 additions & 0 deletions mir/src/import.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::{Ident, Visibility};

pub struct Import {
/// Path that we're importing from
/// e.g. plaid.model in `from plaid.model import ...`
pub path: String,
/// Specific items that are imported
/// e.g. `Account` in `from plaid.model import Account`
pub imports: Vec<ImportItem>,
/// If a wildcard import and if we want to alias, then alias
pub alias: Option<String>,
pub vis: Visibility,
pub feature: Option<String>
}

pub struct ImportItem {
/// This might not conform to standard ident rules for the language, so its a string, not an ident.
pub name: String,
pub alias: Option<String>,
}

impl ImportItem {
pub fn alias(name: &str, alias: &str) -> Self {
Self { name: name.to_string(), alias: Some(alias.to_string()) }
}
}

impl From<&String> for ImportItem {
fn from(s: &String) -> Self {
Self { name: s.clone(), alias: None }
}
}

impl From<String> for ImportItem {
fn from(s: String) -> Self {
Self { name: s, alias: None }
}
}

impl From<&str> for ImportItem {
fn from(s: &str) -> Self {
Self { name: s.to_string(), alias: None }
}
}

impl From<Ident> for ImportItem {
fn from(s: Ident) -> Self {
Self { name: s.0, alias: None }
}
}

Loading

0 comments on commit 363882a

Please sign in to comment.