#![recursion_limit = "256"] use hsr_codegen; use yansi::Paint; use quote::quote; fn assert_diff(left: &str, right: &str) { use diff::Result::*; if left == right { return; } for d in diff::lines(left, right) { match d { Left(l) => println!("{}", Paint::red(format!("- {}", l))), Right(r) => println!("{}", Paint::green(format!("+ {}", r))), Both(l, _) => println!("= {}", l), } } panic!("Bad diff") } #[test] fn build_types_simple() { let _ = env_logger::init(); let yaml = "../example-api/petstore.yaml"; let code = hsr_codegen::generate_from_yaml_file(yaml).unwrap(); // This is the complete expected code generation output // It should compile! let mut expect = quote! { use hsr::actix_web::{App, HttpServer}; use hsr::actix_web::web::{self, Json as AxJson, Query as AxQuery, Path as AxPath, Data as AxData}; use hsr::futures3::future::{BoxFuture as BoxFuture3, FutureExt, TryFutureExt}; use hsr::futures1::Future as Future1; #[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] pub struct Error { pub code: i64, pub message: String } #[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] pub struct NewPet { pub name: String, pub tag: Option } #[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] pub struct Pet { pub id: i64, pub name: String, pub tag: Option } pub type Pets = Vec; #[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] pub struct SomeConflict { pub message: String } #[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] pub enum CreatePetError { E403, E409(SomeConflict), Default(Error) } pub trait Api: Send + Sync + 'static { fn new() -> Self; fn get_all_pets(&self, limit: Option) -> BoxFuture3; fn create_pet(&self, new_pet: NewPet) -> BoxFuture3>; fn get_pet(&self, pet_id: i64) -> BoxFuture3>; } fn get_all_pets(data: AxData, limit: AxQuery>) -> impl Future1, Error = Void> { data.get_all_pets(limit.into_inner()) .map(Ok) .map(|res| res.map(AxJson)) .boxed() .compat() } fn create_pet( data: AxData, new_pet: AxJson, ) -> impl Future1 { data.create_pet(new_pet.into_inner()) .boxed() .compat() } fn get_pet( data: AxData, pet_id: AxPath, ) -> impl Future1, Error = Error> { data.get_pet(pet_id.into_inner()) .map(|res| res.map(AxJson)) .boxed() .compat() } pub fn serve() -> std::io::Result<()> { let api = AxData::new(A::new()); HttpServer::new(move || { App::new() .register_data(api.clone()) .service( web::resource("/pets") .route(web::get().to_async(get_all_pets::)) .route(web::post().to_async(create_pet::)) ) .service( web::resource("/pets/{petId}") .route(web::get().to_async(get_pet::)) ) }) .bind("127.0.0.1:8000")? .run() } } .to_string(); #[cfg(feature = "rustfmt")] { expect = hsr_codegen::prettify_code(expect).unwrap(); } assert_diff(&code, &expect); }