Skip to content

Commit

Permalink
fix #23
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtbuilds committed Dec 15, 2024
1 parent c5a1e36 commit 1ef191f
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 36 deletions.
24 changes: 12 additions & 12 deletions codegen_rust/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::extras::Extras;
use hir::{qualified_env_var, AuthLocation, AuthStrategy, HirSpec, Language, Oauth2Auth, ServerStrategy};
use hir::{Config, Operation};
use libninja_macro::rfunction;
use mir::{import, Class, Field, File, Function, Ident, Item, Visibility};
use mir::{import, Class, Field, File, Function, Ident, Item, Module, Visibility};
use mir_rust::{ToRustCode, ToRustIdent, ToRustType};

/// Generates the client code for a given OpenAPI specification.
Expand Down Expand Up @@ -86,6 +86,7 @@ pub fn make_lib_rs(spec: &HirSpec, extras: &Extras, cfg: &Config) -> File<TokenS
Item::Block(impl_Client),
Item::Block(security),
],
modules: vec![Module::new_pub("request"), Module::new_pub("model")],
}
}

Expand Down Expand Up @@ -234,24 +235,24 @@ pub fn build_api_client_method(operation: &Operation) -> TokenStream {
let name = &operation.name.to_rust_ident();
quote! {
#doc
pub fn #name(&self, #(#fn_args),*) -> FluentRequest<'_, request::#request_struct> {
pub fn #name(&self, #(#fn_args),*) -> FluentRequest<'_, #request_struct> {
FluentRequest {
client: self,
params: request::#request_struct {
params: #request_struct {
#(#struct_field_values,)*
}
}
}
}
}

pub fn impl_ServiceClient_paths(spec: &HirSpec) -> Vec<TokenStream> {
let mut result = vec![];
for operation in &spec.operations {
result.push(build_api_client_method(operation));
}
result
}
// pub fn impl_ServiceClient_paths(spec: &HirSpec) -> Vec<TokenStream> {
// let mut result = vec![];
// for operation in &spec.operations {
// result.push(build_api_client_method(operation));
// }
// result
// }

pub fn authenticate_variant(req: &AuthStrategy, opt: &Config) -> TokenStream {
let auth_struct = opt.authenticator_name().to_rust_struct();
Expand Down Expand Up @@ -324,7 +325,7 @@ pub fn build_Client_authenticate(spec: &HirSpec, opt: &Config) -> TokenStream {

pub fn impl_Client(spec: &HirSpec, opt: &Config) -> TokenStream {
let client_struct_name = opt.client_name();
let path_fns = impl_ServiceClient_paths(spec);
// let path_fns = impl_ServiceClient_paths(spec);

let security = spec.has_security();
let authenticate = security
Expand All @@ -334,7 +335,6 @@ pub fn impl_Client(spec: &HirSpec, opt: &Config) -> TokenStream {
quote! {
impl #client_struct_name {
#authenticate
#(#path_fns)*
}
}
}
Expand Down
10 changes: 7 additions & 3 deletions codegen_rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ pub fn generate_rust_library(spec: HirSpec, cfg: Config) -> Result<()> {

fn write_lib_rs(path: &Path, mut file: File<TokenStream>, m: &mut Modified) -> std::io::Result<()> {
let content = fs::read_to_string(&path).unwrap_or_default();
if content.contains("default_http_client") {
file.items
.retain(|item| !matches!(item, Item::Fn(f) if f.name == "default_http_client"));
let mut c = content.as_str();
if let Some(p) = c.find("libninja: after") {
c = &c[..p];
if c.contains("default_http_client") {
file.items
.retain(|item| !matches!(item, Item::Fn(f) if f.name == "default_http_client"));
}
}
write_with_content(path, file, content, m)
}
Expand Down
35 changes: 16 additions & 19 deletions codegen_rust/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use quote::quote;
use regex::Captures;

use hir::{Config, HirSpec, Language, Location, Operation, Parameter};
use mir::{import, Arg, Class, Doc, Field, File, Function, Ident, Import, Item, Ty, Visibility};
use mir::{import, Arg, Class, Doc, Field, File, Function, Ident, Item, Ty, Visibility};

use mir_rust::{derives_to_tokens, ToRustCode, ToRustIdent, ToRustType};

use crate::{write_rust, Modified};
use crate::{client::build_api_client_method, write_rust, Modified};
use std::io::Result;

pub fn write_request_module(spec: &HirSpec, cfg: &Config, m: &mut Modified) -> Result<()> {
Expand Down Expand Up @@ -63,31 +63,24 @@ pub fn make_single_module(operation: &Operation, spec: &HirSpec, cfg: &Config) -
let struct_name = request_structs[0].name.clone();
let response = operation.ret.to_rust_type();
let method = Ident(operation.method.clone());
// let struct_names = request_structs
// .iter()
// .map(|s| s.name.to_string())
// .collect::<Vec<_>>();
// let request_structs = request_structs
// .into_iter()
// .map(|s| s.to_rust_code())
// .collect::<Vec<_>>();
let url = make_url(&operation);
// modules.push(fname.clone());
// let mut import = Import::new(&fname, struct_names);
// import.vis = Visibility::Public;
// imports.push(import);
let builder_methods = build_request_struct_builder_methods(&operation)
.into_iter()
.map(|s| s.to_rust_code());

let assign_inputs = assign_inputs_to_request(&operation.parameters);
let output = if operation.ret.is_primitive() {
quote! { #response }
} else {
quote! { crate::model::#response }
};

let impl_block = quote! {
impl FluentRequest<'_, #struct_name> {
#(#builder_methods)*
}
impl<'a> ::std::future::IntoFuture for FluentRequest<'a, #struct_name> {
type Output = httpclient::InMemoryResult<#response>;
type Output = httpclient::InMemoryResult<#output>;
type IntoFuture = ::futures::future::BoxFuture<'a, Self::Output>;

fn into_future(self) -> Self::IntoFuture {
Expand All @@ -104,18 +97,22 @@ pub fn make_single_module(operation: &Operation, spec: &HirSpec, cfg: &Config) -
};
let mut items: Vec<Item<TokenStream>> = request_structs.into_iter().map(|s| Item::Class(s)).collect();
items.push(Item::Block(impl_block));
let client_method = build_api_client_method(operation);
items.push(Item::Block(quote! {
impl crate::#client_name {
#client_method
}
}));
File {
attributes: vec![],
doc: None,
imports: vec![
import!(serde_json, json),
import!("crate::model::*"),
import!(crate, FluentRequest),
import!(serde, Serialize, Deserialize),
import!(httpclient, InMemoryResponseExt),
Import::new("crate", vec![client_name]),
],
items,
modules: Vec::new(),
}
}

Expand Down Expand Up @@ -151,7 +148,7 @@ pub fn assign_inputs_to_request(inputs: &[Parameter]) -> TokenStream {
match input.location {
Location::Path => panic!("Should be filtered."),
Location::Body => quote! {
r = r.json(json!({#param_key: #value_identifier}));
r = r.json(serde_json::json!({#param_key: #value_identifier}));
},
Location::Query => quote! {
r = r.query(#param_key, &#value_identifier.to_string());
Expand Down
25 changes: 24 additions & 1 deletion mir/src/file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::interface::Interface;
use crate::{Class, Doc, Enum, Function, Import};
use crate::{Class, Doc, Enum, Function, Import, Visibility};

pub enum Item<T> {
Class(Class<T>),
Expand All @@ -9,10 +9,32 @@ pub enum Item<T> {
Block(T),
}

pub struct Module {
pub name: String,
pub vis: Visibility,
}

impl Module {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
vis: Visibility::Private,
}
}

pub fn new_pub(name: impl Into<String>) -> Self {
Self {
name: name.into(),
vis: Visibility::Public,
}
}
}

pub struct File<T> {
pub attributes: Vec<T>,
pub doc: Option<Doc>,
pub imports: Vec<Import>,
pub modules: Vec<Module>,
/// Code that is before function and class declarations
pub items: Vec<Item<T>>,
}
Expand All @@ -27,6 +49,7 @@ where
doc: None,
imports: vec![],
items: vec![],
modules: Vec::new(),
}
}
}
2 changes: 1 addition & 1 deletion mir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use class::*;
pub use doc::{Doc, DocFormat};
pub use file::{File, Item};
pub use file::{File, Item, Module};
pub use function::{build_dict, build_struct, Arg, Function};
pub use ident::*;
pub use import::*;
Expand Down
9 changes: 9 additions & 0 deletions mir_rust/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ impl ToRustCode for File<TokenStream> {
doc,
mut imports,
mut items,
modules,
} = self;
for m in &mut items {
let Item::Class(m) = m else {
Expand All @@ -21,10 +22,18 @@ impl ToRustCode for File<TokenStream> {
let imports = imports.into_iter().map(|i| i.to_rust_code());
let doc = doc.to_rust_code();
let items = items.into_iter().map(|f| f.to_rust_code());
let modules = modules.into_iter().map(|m| {
let vis = m.vis.to_rust_code();
let name = syn::parse_str::<syn::Ident>(&m.name).unwrap();
quote! {
#vis mod #name;
}
});
quote! {
#(#annotations)*
#doc
#(#imports)*
#(#modules)*
#(#items)*
}
}
Expand Down

0 comments on commit 1ef191f

Please sign in to comment.