mandolin
Generate openapi-based server code
mandolin converts OpenAPI.yaml file into Rust server code. This demo runs with WebAssembly.
preset:
openapi.yaml
openapi_httpservice.yaml
openapi_httpservice_with_auth.yaml
openapi_nesting.yaml
openapi_petstore.yaml
openapi_plant.yaml
openapi: 3.0.3 info: title: Swagger Petstore - OpenAPI 3.0 description: |- This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! You can now help us improve the API whether it's by making changes to the definition itself or to the code. That way, with time, we can improve the API in general, and expose some of the new features in OAS3. _If you're looking for the Swagger 2.0/OAS 2.0 version of Petstore, then click [here](https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml). Alternatively, you can load via the `Edit > Load Petstore OAS 2.0` menu option!_ Some useful links: - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore) - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) termsOfService: http://swagger.io/terms/ contact: email: apiteam@swagger.io license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.11 externalDocs: description: Find out more about Swagger url: http://swagger.io servers: - url: https://petstore3.swagger.io/api/v3 tags: - name: pet description: Everything about your Pets externalDocs: description: Find out more url: http://swagger.io - name: store description: Access to Petstore orders externalDocs: description: Find out more about our store url: http://swagger.io - name: user description: Operations about user paths: /pet: put: tags: - pet summary: Update an existing pet description: Update an existing pet by Id operationId: updatePet requestBody: description: Update an existent pet in the store content: application/json: schema: $ref: '#/components/schemas/Pet' application/xml: schema: $ref: '#/components/schemas/Pet' application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/Pet' required: true responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Pet' application/xml: schema: $ref: '#/components/schemas/Pet' '400': description: Invalid ID supplied '404': description: Pet not found '422': description: Validation exception security: - petstore_auth: - write:pets - read:pets post: tags: - pet summary: Add a new pet to the store description: Add a new pet to the store operationId: addPet requestBody: description: Create a new pet in the store content: application/json: schema: $ref: '#/components/schemas/Pet' application/xml: schema: $ref: '#/components/schemas/Pet' application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/Pet' required: true responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/Pet' application/xml: schema: $ref: '#/components/schemas/Pet' '400': description: Invalid input '422': description: Validation exception security: - petstore_auth: - write:pets - read:pets /pet/findByStatus: get: tags: - pet summary: Finds Pets by status description: Multiple status values can be provided with comma separated strings operationId: findPetsByStatus parameters: - name: status in: query description: Status values that need to be considered for filter required: false explode: true schema: type: string default: available enum: - available - pending - sold responses: '200': description: successful operation content: application/json: schema: type: array items: $ref: '#/components/schemas/Pet' application/xml: schema: type: array items: $ref: '#/components/schemas/Pet' '400': description: Invalid status value security: - petstore_auth: - write:pets - read:pets /pet/findByTags: get: tags: - pet summary: Finds Pets by tags description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. operationId: findPetsByTags parameters: - name: tags in: query description: Tags to filter by required: false explode: true schema: type: array items: type: string responses: '200': description: successful operation content: application/json: schema: type: array items: $ref: '#/components/schemas/Pet' application/xml: schema: type: array items: $ref: '#/components/schemas/Pet' '400': description: Invalid tag value security: - petstore_auth: - write:pets - read:pets /pet/{petId}: get: tags: - pet summary: Find pet by ID description: Returns a single pet operationId: getPetById parameters: - name: petId in: path description: ID of pet to return required: true schema: type: integer format: int64 responses: '200': description: successful operation content: application/json: schema: $ref: '#/components/schemas/Pet' application/xml: schema: $ref: '#/components/schemas/Pet' '400': description: Invalid ID supplied '404': description: Pet not found security: - api_key: [] - petstore_auth: - write:pets - read:pets post: tags: - pet summary: Updates a pet in the store with form openapi description: '' operationId: updatePetWithForm parameters: - name: petId in: path description: ID of pet that needs to be updated required: true schema: type: integer format: int64 - name: name in: query description: Name of pet that needs to be updated schema: type: string - name: status in: query description: Status of pet that needs to be updated schema: type: string responses: '400': description: Invalid input security: - petstore_auth: - write:pets - read:pets delete: tags: - pet summary: Deletes a pet description: delete a pet operationId: deletePet parameters: - name: api_key in: header description: '' required: false schema: type: string - name: petId in: path description: Pet id to delete required: true schema: type: integer format: int64 responses: '400': description: Invalid pet value security: - petstore_auth: - write:pets - read:pets /pet/{petId}/uploadImage: post: tags: - pet summary: uploads an image description: '' operationId: uploadFile parameters: - name: petId in: path description: ID of pet to update required: true schema: type: integer format: int64 - name: additionalMetadata in: query description: Additional Metadata required: false schema: type: string requestBody: content: application/octet-stream: schema: type: string format: binary responses: '200': description: successful operation content: application/json: schema: $ref: '#/components/schemas/ApiResponse' security: - petstore_auth: - write:pets - read:pets /store/inventory: get: tags: - store summary: Returns pet inventories by status description: Returns a map of status codes to quantities operationId: getInventory responses: '200': description: successful operation content: application/json: schema: type: object additionalProperties: type: integer format: int32 security: - api_key: [] /store/order: post: tags: - store summary: Place an order for a pet description: Place a new order in the store operationId: placeOrder requestBody: content: application/json: schema: $ref: '#/components/schemas/Order' application/xml: schema: $ref: '#/components/schemas/Order' application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/Order' responses: '200': description: successful operation content: application/json: schema: $ref: '#/components/schemas/Order' '400': description: Invalid input '422': description: Validation exception /store/order/{orderId}: get: tags: - store summary: Find purchase order by ID description: For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions. operationId: getOrderById parameters: - name: orderId in: path description: ID of order that needs to be fetched required: true schema: type: integer format: int64 responses: '200': description: successful operation content: application/json: schema: $ref: '#/components/schemas/Order' application/xml: schema: $ref: '#/components/schemas/Order' '400': description: Invalid ID supplied '404': description: Order not found delete: tags: - store summary: Delete purchase order by ID description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors operationId: deleteOrder parameters: - name: orderId in: path description: ID of the order that needs to be deleted required: true schema: type: integer format: int64 responses: '400': description: Invalid ID supplied '404': description: Order not found /user: post: tags: - user summary: Create user description: This can only be done by the logged in user. operationId: createUser requestBody: description: Created user object content: application/json: schema: $ref: '#/components/schemas/User' application/xml: schema: $ref: '#/components/schemas/User' application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/User' responses: default: description: successful operation content: application/json: schema: $ref: '#/components/schemas/User' application/xml: schema: $ref: '#/components/schemas/User' /user/createWithList: post: tags: - user summary: Creates list of users with given input array description: Creates list of users with given input array operationId: createUsersWithListInput requestBody: content: application/json: schema: type: array items: $ref: '#/components/schemas/User' responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/User' application/xml: schema: $ref: '#/components/schemas/User' default: description: successful operation /user/login: get: tags: - user summary: Logs user into the system description: '' operationId: loginUser parameters: - name: username in: query description: The user name for login required: false schema: type: string - name: password in: query description: The password for login in clear text required: false schema: type: string responses: '200': description: successful operation headers: X-Rate-Limit: description: calls per hour allowed by the user schema: type: integer format: int32 X-Expires-After: description: date in UTC when token expires schema: type: string format: date-time content: application/xml: schema: type: string application/json: schema: type: string '400': description: Invalid username/password supplied /user/logout: get: tags: - user summary: Logs out current logged in user session description: '' operationId: logoutUser parameters: [] responses: default: description: successful operation /user/{username}: get: tags: - user summary: Get user by user name description: '' operationId: getUserByName parameters: - name: username in: path description: 'The name that needs to be fetched. Use user1 for testing. ' required: true schema: type: string responses: '200': description: successful operation content: application/json: schema: $ref: '#/components/schemas/User' application/xml: schema: $ref: '#/components/schemas/User' '400': description: Invalid username supplied '404': description: User not found put: tags: - user summary: Update user description: This can only be done by the logged in user. operationId: updateUser parameters: - name: username in: path description: name that need to be deleted required: true schema: type: string requestBody: description: Update an existent user in the store content: application/json: schema: $ref: '#/components/schemas/User' application/xml: schema: $ref: '#/components/schemas/User' application/x-www-form-urlencoded: schema: $ref: '#/components/schemas/User' responses: default: description: successful operation delete: tags: - user summary: Delete user description: This can only be done by the logged in user. operationId: deleteUser parameters: - name: username in: path description: The name that needs to be deleted required: true schema: type: string responses: '400': description: Invalid username supplied '404': description: User not found components: schemas: Order: type: object properties: id: type: integer format: int64 example: 10 petId: type: integer format: int64 example: 198772 quantity: type: integer format: int32 example: 7 shipDate: type: string format: date-time status: type: string description: Order Status example: approved enum: - placed - approved - delivered complete: type: boolean xml: name: order Customer: type: object properties: id: type: integer format: int64 example: 100000 username: type: string example: fehguy address: type: array xml: name: addresses wrapped: true items: $ref: '#/components/schemas/Address' xml: name: customer Address: type: object properties: street: type: string example: 437 Lytton city: type: string example: Palo Alto state: type: string example: CA zip: type: string example: '94301' xml: name: address Category: type: object properties: id: type: integer format: int64 example: 1 name: type: string example: Dogs xml: name: category User: type: object properties: id: type: integer format: int64 example: 10 username: type: string example: theUser firstName: type: string example: John lastName: type: string example: James email: type: string example: john@email.com password: type: string example: '12345' phone: type: string example: '12345' userStatus: type: integer description: User Status format: int32 example: 1 xml: name: user Tag: type: object properties: id: type: integer format: int64 name: type: string xml: name: tag Pet: required: - name - photoUrls type: object properties: id: type: integer format: int64 example: 10 name: type: string example: doggie category: $ref: '#/components/schemas/Category' photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl tags: type: array xml: wrapped: true items: $ref: '#/components/schemas/Tag' status: type: string description: pet status in the store enum: - available - pending - sold xml: name: pet ApiResponse: type: object properties: code: type: integer format: int32 type: type: string message: type: string xml: name: '##default' requestBodies: Pet: description: Pet object that needs to be added to the store content: application/json: schema: $ref: '#/components/schemas/Pet' application/xml: schema: $ref: '#/components/schemas/Pet' UserArray: description: List of user object content: application/json: schema: type: array items: $ref: '#/components/schemas/User' securitySchemes: petstore_auth: type: oauth2 flows: implicit: authorizationUrl: https://petstore3.swagger.io/oauth/authorize scopes: write:pets: modify pets in your account read:pets: read your pets api_key: type: apiKey name: api_key in: header
â
#![allow(non_camel_case_types)] #![allow(unused_variables)] // mandolin generates this code #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct Address{ pub r#city:Option<String>, pub r#state:Option<String>, pub r#street:Option<String>, pub r#zip:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct ApiResponse{ pub r#code:Option<i32>, pub r#message:Option<String>, pub r#type:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct Category{ pub r#id:Option<i64>, pub r#name:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct Customer{ pub r#address:Option<Vec<Address>>, pub r#id:Option<i64>, pub r#username:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct Order{ pub r#complete:Option<bool>, pub r#id:Option<i64>, pub r#petId:Option<i64>, pub r#quantity:Option<i32>, pub r#shipDate:Option<String>, pub r#status:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct Pet{ pub r#category:Option<Category>, pub r#id:Option<i64>, pub r#name:String, pub r#photoUrls:Vec<String>, pub r#status:Option<String>, pub r#tags:Option<Vec<Tag>>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct Tag{ pub r#id:Option<i64>, pub r#name:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct User{ pub r#email:Option<String>, pub r#firstName:Option<String>, pub r#id:Option<i64>, pub r#lastName:Option<String>, pub r#password:Option<String>, pub r#phone:Option<String>, pub r#userStatus:Option<i32>, pub r#username:Option<String>, } #[derive(Default,Clone,Debug,serde::Serialize,serde::Deserialize)] pub struct PathsStoreInventoryGetResponses200ContentApplicationJsonSchema{HashMap<String,i32> }use std::collections::HashMap; use serde; use std::future::Future; pub trait Server{ // post /pet fn add_pet(request: AddPetRequest) -> impl Future<Output = AddPetResponse> + Send{async{Default::default()}} // put /pet fn update_pet(request: UpdatePetRequest) -> impl Future<Output = UpdatePetResponse> + Send{async{Default::default()}} // get /pet/findByStatus fn find_pets_by_status(request: FindPetsByStatusRequest) -> impl Future<Output = FindPetsByStatusResponse> + Send{async{Default::default()}} // get /pet/findByTags fn find_pets_by_tags(request: FindPetsByTagsRequest) -> impl Future<Output = FindPetsByTagsResponse> + Send{async{Default::default()}} // delete /pet/{petId} fn delete_pet(request: DeletePetRequest) -> impl Future<Output = DeletePetResponse> + Send{async{Default::default()}} // get /pet/{petId} fn get_pet_by_id(request: GetPetByIdRequest) -> impl Future<Output = GetPetByIdResponse> + Send{async{Default::default()}} // post /pet/{petId} fn update_pet_with_form(request: UpdatePetWithFormRequest) -> impl Future<Output = UpdatePetWithFormResponse> + Send{async{Default::default()}} // post /pet/{petId}/uploadImage fn upload_file(request: UploadFileRequest) -> impl Future<Output = UploadFileResponse> + Send{async{Default::default()}} // get /store/inventory fn get_inventory(request: GetInventoryRequest) -> impl Future<Output = GetInventoryResponse> + Send{async{Default::default()}} // post /store/order fn place_order(request: PlaceOrderRequest) -> impl Future<Output = PlaceOrderResponse> + Send{async{Default::default()}} // delete /store/order/{orderId} fn delete_order(request: DeleteOrderRequest) -> impl Future<Output = DeleteOrderResponse> + Send{async{Default::default()}} // get /store/order/{orderId} fn get_order_by_id(request: GetOrderByIdRequest) -> impl Future<Output = GetOrderByIdResponse> + Send{async{Default::default()}} // post /user fn create_user(request: CreateUserRequest) -> impl Future<Output = CreateUserResponse> + Send{async{Default::default()}} // post /user/createWithList fn create_users_with_list_input(request: CreateUsersWithListInputRequest) -> impl Future<Output = CreateUsersWithListInputResponse> + Send{async{Default::default()}} // get /user/login fn login_user(request: LoginUserRequest) -> impl Future<Output = LoginUserResponse> + Send{async{Default::default()}} // get /user/logout fn logout_user(request: LogoutUserRequest) -> impl Future<Output = LogoutUserResponse> + Send{async{Default::default()}} // delete /user/{username} fn delete_user(request: DeleteUserRequest) -> impl Future<Output = DeleteUserResponse> + Send{async{Default::default()}} // get /user/{username} fn get_user_by_name(request: GetUserByNameRequest) -> impl Future<Output = GetUserByNameResponse> + Send{async{Default::default()}} // put /user/{username} fn update_user(request: UpdateUserRequest) -> impl Future<Output = UpdateUserResponse> + Send{async{Default::default()}} } /* pub struct TestServer{} impl server::Server for TestServer{ // post /pet async fn add_pet(request: ) -> {Default::default()} // put /pet async fn update_pet(request: ) -> {Default::default()} // get /pet/findByStatus async fn find_pets_by_status(request: ) -> {Default::default()} // get /pet/findByTags async fn find_pets_by_tags(request: ) -> {Default::default()} // delete /pet/{petId} async fn delete_pet(request: ) -> {Default::default()} // get /pet/{petId} async fn get_pet_by_id(request: ) -> {Default::default()} // post /pet/{petId} async fn update_pet_with_form(request: ) -> {Default::default()} // post /pet/{petId}/uploadImage async fn upload_file(request: ) -> {Default::default()} // get /store/inventory async fn get_inventory(request: ) -> {Default::default()} // post /store/order async fn place_order(request: ) -> {Default::default()} // delete /store/order/{orderId} async fn delete_order(request: ) -> {Default::default()} // get /store/order/{orderId} async fn get_order_by_id(request: ) -> {Default::default()} // post /user async fn create_user(request: ) -> {Default::default()} // post /user/createWithList async fn create_users_with_list_input(request: ) -> {Default::default()} // get /user/login async fn login_user(request: ) -> {Default::default()} // get /user/logout async fn logout_user(request: ) -> {Default::default()} // delete /user/{username} async fn delete_user(request: ) -> {Default::default()} // get /user/{username} async fn get_user_by_name(request: ) -> {Default::default()} // put /user/{username} async fn update_user(request: ) -> {Default::default()} } */ // Request of add_pet #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct AddPetRequest{ pub body:Pet pub body:Pet pub body:Pet } // Response of add_pet #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum AddPetResponse{ Status200(PetPet), Status400, Status422, } impl Default for AddPetResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of update_pet #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct UpdatePetRequest{ pub body:Pet pub body:Pet pub body:Pet } // Response of update_pet #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum UpdatePetResponse{ Status200(PetPet), Status400, Status404, Status422, } impl Default for UpdatePetResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of find_pets_by_status #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct FindPetsByStatusRequest{ pub status:Option<String>, } // Response of find_pets_by_status #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum FindPetsByStatusResponse{ Status200(Vec<Pet>Vec<Pet>), Status400, } impl Default for FindPetsByStatusResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of find_pets_by_tags #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct FindPetsByTagsRequest{ pub tags:Option<Vec<String>>, } // Response of find_pets_by_tags #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum FindPetsByTagsResponse{ Status200(Vec<Pet>Vec<Pet>), Status400, } impl Default for FindPetsByTagsResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of delete_pet #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct DeletePetRequest{ pub api_key:Option<String>, pub petId:i64, } // Response of delete_pet #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum DeletePetResponse{ Status400, } impl Default for DeletePetResponse{ fn default() -> Self{ Self::Status400 } } // Request of get_pet_by_id #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct GetPetByIdRequest{ pub petId:i64, } // Response of get_pet_by_id #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum GetPetByIdResponse{ Status200(PetPet), Status400, Status404, } impl Default for GetPetByIdResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of update_pet_with_form #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct UpdatePetWithFormRequest{ pub petId:i64, pub name:Option<String>, pub status:Option<String>, } // Response of update_pet_with_form #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum UpdatePetWithFormResponse{ Status400, } impl Default for UpdatePetWithFormResponse{ fn default() -> Self{ Self::Status400 } } // Request of upload_file #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct UploadFileRequest{ pub petId:i64, pub additionalMetadata:Option<String>, pub body:Vec<u8> } // Response of upload_file #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum UploadFileResponse{ Status200(ApiResponse), } impl Default for UploadFileResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of get_inventory #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct GetInventoryRequest{ } // Response of get_inventory #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum GetInventoryResponse{ Status200(HashMap<String,i32>), } impl Default for GetInventoryResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of place_order #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct PlaceOrderRequest{ pub body:Order pub body:Order pub body:Order } // Response of place_order #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum PlaceOrderResponse{ Status200(Order), Status400, Status422, } impl Default for PlaceOrderResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of delete_order #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct DeleteOrderRequest{ pub orderId:i64, } // Response of delete_order #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum DeleteOrderResponse{ Status400, Status404, } impl Default for DeleteOrderResponse{ fn default() -> Self{ Self::Status400 } } // Request of get_order_by_id #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct GetOrderByIdRequest{ pub orderId:i64, } // Response of get_order_by_id #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum GetOrderByIdResponse{ Status200(OrderOrder), Status400, Status404, } impl Default for GetOrderByIdResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of create_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct CreateUserRequest{ pub body:User pub body:User pub body:User } // Response of create_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum CreateUserResponse{ StatusDefault(UserUser), } impl Default for CreateUserResponse{ fn default() -> Self{ Self::Statusdefault(Default::default()) } } // Request of create_users_with_list_input #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct CreateUsersWithListInputRequest{ pub body:Vec<User> } // Response of create_users_with_list_input #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum CreateUsersWithListInputResponse{ Status200(UserUser), StatusDefault, } impl Default for CreateUsersWithListInputResponse{ fn default() -> Self{ Self::Statusdefault } } // Request of login_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct LoginUserRequest{ pub username:Option<String>, pub password:Option<String>, } // Response of login_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum LoginUserResponse{ Status200(StringString), Status400, } impl Default for LoginUserResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of logout_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct LogoutUserRequest{ } // Response of logout_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum LogoutUserResponse{ StatusDefault, } impl Default for LogoutUserResponse{ fn default() -> Self{ Self::Statusdefault } } // Request of delete_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct DeleteUserRequest{ pub username:String, } // Response of delete_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum DeleteUserResponse{ Status400, Status404, } impl Default for DeleteUserResponse{ fn default() -> Self{ Self::Status400 } } // Request of get_user_by_name #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct GetUserByNameRequest{ pub username:String, } // Response of get_user_by_name #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum GetUserByNameResponse{ Status200(UserUser), Status400, Status404, } impl Default for GetUserByNameResponse{ fn default() -> Self{ Self::Status200(Default::default()) } } // Request of update_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub struct UpdateUserRequest{ pub username:String, pub body:User pub body:User pub body:User } // Response of update_user #[derive(serde::Serialize,serde::Deserialize,Debug)] pub enum UpdateUserResponse{ StatusDefault, } impl Default for UpdateUserResponse{ fn default() -> Self{ Self::Statusdefault } } use axum; pub fn axum_router_operations<S:Server>()->axum::Router{ axum::Router::new() .route("/pet", axum::routing::post(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::add_pet(AddPetRequest{ body:match serde_json::from_slice(body.to_vec().as_slice()){Ok(v)=>v,Err(v) => { return (axum::http::StatusCode::INTERNAL_SERVER_ERROR,[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("{:?}", v).as_bytes().to_vec())}} body:body.into() body:body.into() }).await; match ret{ AddPetResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), AddPetResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid input".as_bytes().to_vec()), AddPetResponse::Status422=> (axum::http::StatusCode::from_u16(422).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Validation exception".as_bytes().to_vec()), } })) .route("/pet", axum::routing::put(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::update_pet(UpdatePetRequest{ body:match serde_json::from_slice(body.to_vec().as_slice()){Ok(v)=>v,Err(v) => { return (axum::http::StatusCode::INTERNAL_SERVER_ERROR,[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("{:?}", v).as_bytes().to_vec())}} body:body.into() body:body.into() }).await; match ret{ UpdatePetResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), UpdatePetResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid ID supplied".as_bytes().to_vec()), UpdatePetResponse::Status404=> (axum::http::StatusCode::from_u16(404).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Pet not found".as_bytes().to_vec()), UpdatePetResponse::Status422=> (axum::http::StatusCode::from_u16(422).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Validation exception".as_bytes().to_vec()), } })) .route("/pet/findByStatus", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::find_pets_by_status(FindPetsByStatusRequest{ r#status:match query.get("status").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, }).await; match ret{ FindPetsByStatusResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), FindPetsByStatusResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid status value".as_bytes().to_vec()), } })) .route("/pet/findByTags", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::find_pets_by_tags(FindPetsByTagsRequest{ r#tags:match query.get("tags").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, }).await; match ret{ FindPetsByTagsResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), FindPetsByTagsResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid tag value".as_bytes().to_vec()), } })) .route("/pet/{petId}", axum::routing::delete(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::delete_pet(DeletePetRequest{ r#api_key:match header.get("api_key").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, r#petId:match path.get("petId").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: petId in path={:?}", path).as_bytes().to_vec())}, }).await; match ret{ DeletePetResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid pet value".as_bytes().to_vec()), } })) .route("/pet/{petId}", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::get_pet_by_id(GetPetByIdRequest{ r#petId:match path.get("petId").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: petId in path={:?}", path).as_bytes().to_vec())}, }).await; match ret{ GetPetByIdResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), GetPetByIdResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid ID supplied".as_bytes().to_vec()), GetPetByIdResponse::Status404=> (axum::http::StatusCode::from_u16(404).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Pet not found".as_bytes().to_vec()), } })) .route("/pet/{petId}", axum::routing::post(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::update_pet_with_form(UpdatePetWithFormRequest{ r#petId:match path.get("petId").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: petId in path={:?}", path).as_bytes().to_vec())}, r#name:match query.get("name").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, r#status:match query.get("status").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, }).await; match ret{ UpdatePetWithFormResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid input".as_bytes().to_vec()), } })) .route("/pet/{petId}/uploadImage", axum::routing::post(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::upload_file(UploadFileRequest{ r#petId:match path.get("petId").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: petId in path={:?}", path).as_bytes().to_vec())}, r#additionalMetadata:match query.get("additionalMetadata").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, body:body.into() }).await; match ret{ UploadFileResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json")), } })) .route("/store/inventory", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::get_inventory(GetInventoryRequest{ }).await; match ret{ GetInventoryResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json")), } })) .route("/store/order", axum::routing::post(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::place_order(PlaceOrderRequest{ body:match serde_json::from_slice(body.to_vec().as_slice()){Ok(v)=>v,Err(v) => { return (axum::http::StatusCode::INTERNAL_SERVER_ERROR,[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("{:?}", v).as_bytes().to_vec())}} body:body.into() body:body.into() }).await; match ret{ PlaceOrderResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json")), PlaceOrderResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid input".as_bytes().to_vec()), PlaceOrderResponse::Status422=> (axum::http::StatusCode::from_u16(422).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Validation exception".as_bytes().to_vec()), } })) .route("/store/order/{orderId}", axum::routing::delete(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::delete_order(DeleteOrderRequest{ r#orderId:match path.get("orderId").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: orderId in path={:?}", path).as_bytes().to_vec())}, }).await; match ret{ DeleteOrderResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid ID supplied".as_bytes().to_vec()), DeleteOrderResponse::Status404=> (axum::http::StatusCode::from_u16(404).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Order not found".as_bytes().to_vec()), } })) .route("/store/order/{orderId}", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::get_order_by_id(GetOrderByIdRequest{ r#orderId:match path.get("orderId").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: orderId in path={:?}", path).as_bytes().to_vec())}, }).await; match ret{ GetOrderByIdResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), GetOrderByIdResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid ID supplied".as_bytes().to_vec()), GetOrderByIdResponse::Status404=> (axum::http::StatusCode::from_u16(404).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Order not found".as_bytes().to_vec()), } })) .route("/user", axum::routing::post(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::create_user(CreateUserRequest{ body:match serde_json::from_slice(body.to_vec().as_slice()){Ok(v)=>v,Err(v) => { return (axum::http::StatusCode::INTERNAL_SERVER_ERROR,[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("{:?}", v).as_bytes().to_vec())}} body:body.into() body:body.into() }).await; match ret{ CreateUserResponse::Statusdefault(v)=> (axum::http::StatusCode::from_u16(default).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), } })) .route("/user/createWithList", axum::routing::post(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::create_users_with_list_input(CreateUsersWithListInputRequest{ body:match serde_json::from_slice(body.to_vec().as_slice()){Ok(v)=>v,Err(v) => { return (axum::http::StatusCode::INTERNAL_SERVER_ERROR,[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("{:?}", v).as_bytes().to_vec())}} }).await; match ret{ CreateUsersWithListInputResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), CreateUsersWithListInputResponse::Statusdefault=> (axum::http::StatusCode::from_u16(default).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "successful operation".as_bytes().to_vec()), } })) .route("/user/login", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::login_user(LoginUserRequest{ r#username:match query.get("username").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, r#password:match query.get("password").and_then(|v| v.parse().ok()){Some(v)=>Some(v), None=>None}, }).await; match ret{ LoginUserResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), LoginUserResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid username/password supplied".as_bytes().to_vec()), } })) .route("/user/logout", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::logout_user(LogoutUserRequest{ }).await; match ret{ LogoutUserResponse::Statusdefault=> (axum::http::StatusCode::from_u16(default).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "successful operation".as_bytes().to_vec()), } })) .route("/user/{username}", axum::routing::delete(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::delete_user(DeleteUserRequest{ r#username:match path.get("username").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: username in path={:?}", path).as_bytes().to_vec())}, }).await; match ret{ DeleteUserResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid username supplied".as_bytes().to_vec()), DeleteUserResponse::Status404=> (axum::http::StatusCode::from_u16(404).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "User not found".as_bytes().to_vec()), } })) .route("/user/{username}", axum::routing::get(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, | async move{ let ret=S::get_user_by_name(GetUserByNameRequest{ r#username:match path.get("username").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: username in path={:?}", path).as_bytes().to_vec())}, }).await; match ret{ GetUserByNameResponse::Status200(v)=> (axum::http::StatusCode::from_u16(200).unwrap(), [(axum::http::header::CONTENT_TYPE, "application/json")],serde_json::to_vec_pretty(&v).expect("error serialize response json") [(axum::http::header::CONTENT_TYPE, "application/xml")],v.as_bytes().to_vec()), GetUserByNameResponse::Status400=> (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "Invalid username supplied".as_bytes().to_vec()), GetUserByNameResponse::Status404=> (axum::http::StatusCode::from_u16(404).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "User not found".as_bytes().to_vec()), } })) .route("/user/{username}", axum::routing::put(| path: axum::extract::Path<HashMap<String,String>>, query: axum::extract::Query<HashMap<String,String>>, header: axum::http::HeaderMap, body: axum::body::Bytes, | async move{ let ret=S::update_user(UpdateUserRequest{ r#username:match path.get("username").and_then(|v| v.parse().ok()){Some(v)=>v, None=>return (axum::http::StatusCode::from_u16(400).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("parse error: username in path={:?}", path).as_bytes().to_vec())}, body:match serde_json::from_slice(body.to_vec().as_slice()){Ok(v)=>v,Err(v) => { return (axum::http::StatusCode::INTERNAL_SERVER_ERROR,[(axum::http::header::CONTENT_TYPE, "text/plain")], format!("{:?}", v).as_bytes().to_vec())}} body:body.into() body:body.into() }).await; match ret{ UpdateUserResponse::Statusdefault=> (axum::http::StatusCode::from_u16(default).unwrap(),[(axum::http::header::CONTENT_TYPE, "text/plain")], "successful operation".as_bytes().to_vec()), } })) .route("/openapi.json", axum::routing::get(|| async move{ r###"{"components":{"requestBodies":{"Pet":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Pet"}}},"description":"Pet object that needs to be added to the store"},"UserArray":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/User"},"type":"array"}}},"description":"List of user object"}},"schemas":{"Address":{"properties":{"city":{"example":"Palo Alto","type":"string"},"state":{"example":"CA","type":"string"},"street":{"example":"437 Lytton","type":"string"},"zip":{"example":"94301","type":"string"}},"type":"object"},"ApiResponse":{"properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"},"type":{"type":"string"}},"type":"object"},"Category":{"properties":{"id":{"example":1,"format":"int64","type":"integer"},"name":{"example":"Dogs","type":"string"}},"type":"object"},"Customer":{"properties":{"address":{"items":{"$ref":"#/components/schemas/Address"},"type":"array"},"id":{"example":100000,"format":"int64","type":"integer"},"username":{"example":"fehguy","type":"string"}},"type":"object"},"Order":{"properties":{"complete":{"type":"boolean"},"id":{"example":10,"format":"int64","type":"integer"},"petId":{"example":198772,"format":"int64","type":"integer"},"quantity":{"example":7,"format":"int32","type":"integer"},"shipDate":{"format":"date-time","type":"string"},"status":{"description":"Order Status","enum":["placed","approved","delivered"],"example":"approved","type":"string"}},"type":"object"},"Pet":{"properties":{"category":{"$ref":"#/components/schemas/Category"},"id":{"example":10,"format":"int64","type":"integer"},"name":{"example":"doggie","type":"string"},"photoUrls":{"items":{"type":"string"},"type":"array"},"status":{"description":"pet status in the store","enum":["available","pending","sold"],"type":"string"},"tags":{"items":{"$ref":"#/components/schemas/Tag"},"type":"array"}},"required":["name","photoUrls"],"type":"object"},"Tag":{"properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"}},"type":"object"},"User":{"properties":{"email":{"example":"john@email.com","type":"string"},"firstName":{"example":"John","type":"string"},"id":{"example":10,"format":"int64","type":"integer"},"lastName":{"example":"James","type":"string"},"password":{"example":"12345","type":"string"},"phone":{"example":"12345","type":"string"},"userStatus":{"description":"User Status","example":1,"format":"int32","type":"integer"},"username":{"example":"theUser","type":"string"}},"type":"object"}},"securitySchemes":{"api_key":{"in":"header","name":"api_key","type":"apiKey"},"petstore_auth":{"flows":{"implicit":{"authorizationUrl":"https://petstore3.swagger.io/oauth/authorize","scopes":{"read:pets":"read your pets","write:pets":"modify pets in your account"}}},"type":"oauth2"}}},"externalDocs":{"description":"Find out more about Swagger","url":"http://swagger.io"},"info":{"contact":{"email":"apiteam@swagger.io"},"description":"This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about\nSwagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we\u0027ve switched to the design first approach!\nYou can now help us improve the API whether it\u0027s by making changes to the definition itself or to the code.\nThat way, with time, we can improve the API in general, and expose some of the new features in OAS3.\n\n_If you\u0027re looking for the Swagger 2.0/OAS 2.0 version of Petstore, then click [here](https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml). Alternatively, you can load via the `Edit \u003e Load Petstore OAS 2.0` menu option!_\n\nSome useful links:\n- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)\n- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)","license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"},"termsOfService":"http://swagger.io/terms/","title":"Swagger Petstore - OpenAPI 3.0","version":"1.0.11"},"openapi":"3.0.3","paths":{"/pet":{"post":{"description":"Add a new pet to the store","operationId":"addPet","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Pet"}}},"description":"Create a new pet in the store","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Pet"}}},"description":"Successful operation"},"400":{"description":"Invalid input"},"422":{"description":"Validation exception"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"Add a new pet to the store","tags":["pet"]},"put":{"description":"Update an existing pet by Id","operationId":"updatePet","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Pet"}}},"description":"Update an existent pet in the store","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Pet"}}},"description":"Successful operation"},"400":{"description":"Invalid ID supplied"},"404":{"description":"Pet not found"},"422":{"description":"Validation exception"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"Update an existing pet","tags":["pet"]}},"/pet/findByStatus":{"get":{"description":"Multiple status values can be provided with comma separated strings","operationId":"findPetsByStatus","parameters":[{"description":"Status values that need to be considered for filter","explode":true,"in":"query","name":"status","schema":{"default":"available","enum":["available","pending","sold"],"type":"string"},"style":"form"}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Pet"},"type":"array"}},"application/xml":{"schema":{"items":{"$ref":"#/components/schemas/Pet"},"type":"array"}}},"description":"successful operation"},"400":{"description":"Invalid status value"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"Finds Pets by status","tags":["pet"]}},"/pet/findByTags":{"get":{"description":"Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.","operationId":"findPetsByTags","parameters":[{"description":"Tags to filter by","explode":true,"in":"query","name":"tags","schema":{"items":{"type":"string"},"type":"array"},"style":"form"}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Pet"},"type":"array"}},"application/xml":{"schema":{"items":{"$ref":"#/components/schemas/Pet"},"type":"array"}}},"description":"successful operation"},"400":{"description":"Invalid tag value"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"Finds Pets by tags","tags":["pet"]}},"/pet/{petId}":{"delete":{"description":"delete a pet","operationId":"deletePet","parameters":[{"description":"","in":"header","name":"api_key","schema":{"type":"string"},"style":"simple"},{"description":"Pet id to delete","in":"path","name":"petId","required":true,"schema":{"format":"int64","type":"integer"},"style":"simple"}],"responses":{"400":{"description":"Invalid pet value"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"Deletes a pet","tags":["pet"]},"get":{"description":"Returns a single pet","operationId":"getPetById","parameters":[{"description":"ID of pet to return","in":"path","name":"petId","required":true,"schema":{"format":"int64","type":"integer"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pet"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Pet"}}},"description":"successful operation"},"400":{"description":"Invalid ID supplied"},"404":{"description":"Pet not found"}},"security":[{"api_key":[]},{"petstore_auth":["write:pets","read:pets"]}],"summary":"Find pet by ID","tags":["pet"]},"post":{"description":"","operationId":"updatePetWithForm","parameters":[{"description":"ID of pet that needs to be updated","in":"path","name":"petId","required":true,"schema":{"format":"int64","type":"integer"},"style":"simple"},{"description":"Name of pet that needs to be updated","in":"query","name":"name","schema":{"type":"string"},"style":"form"},{"description":"Status of pet that needs to be updated","in":"query","name":"status","schema":{"type":"string"},"style":"form"}],"responses":{"400":{"description":"Invalid input"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"Updates a pet in the store with form openapi","tags":["pet"]}},"/pet/{petId}/uploadImage":{"post":{"description":"","operationId":"uploadFile","parameters":[{"description":"ID of pet to update","in":"path","name":"petId","required":true,"schema":{"format":"int64","type":"integer"},"style":"simple"},{"description":"Additional Metadata","in":"query","name":"additionalMetadata","schema":{"type":"string"},"style":"form"}],"requestBody":{"content":{"application/octet-stream":{"schema":{"format":"binary","type":"string"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}},"description":"successful operation"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"summary":"uploads an image","tags":["pet"]}},"/store/inventory":{"get":{"description":"Returns a map of status codes to quantities","operationId":"getInventory","responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":{"format":"int32","type":"integer"},"type":"object"}}},"description":"successful operation"}},"security":[{"api_key":[]}],"summary":"Returns pet inventories by status","tags":["store"]}},"/store/order":{"post":{"description":"Place a new order in the store","operationId":"placeOrder","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Order"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Order"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":"successful operation"},"400":{"description":"Invalid input"},"422":{"description":"Validation exception"}},"summary":"Place an order for a pet","tags":["store"]}},"/store/order/{orderId}":{"delete":{"description":"For valid response try integer IDs with value \u003c 1000. Anything above 1000 or nonintegers will generate API errors","operationId":"deleteOrder","parameters":[{"description":"ID of the order that needs to be deleted","in":"path","name":"orderId","required":true,"schema":{"format":"int64","type":"integer"},"style":"simple"}],"responses":{"400":{"description":"Invalid ID supplied"},"404":{"description":"Order not found"}},"summary":"Delete purchase order by ID","tags":["store"]},"get":{"description":"For valid response try integer IDs with value \u003c= 5 or \u003e 10. Other values will generate exceptions.","operationId":"getOrderById","parameters":[{"description":"ID of order that needs to be fetched","in":"path","name":"orderId","required":true,"schema":{"format":"int64","type":"integer"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}},"application/xml":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":"successful operation"},"400":{"description":"Invalid ID supplied"},"404":{"description":"Order not found"}},"summary":"Find purchase order by ID","tags":["store"]}},"/user":{"post":{"description":"This can only be done by the logged in user.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/User"}},"application/xml":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"Created user object"},"responses":{"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}},"application/xml":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"successful operation"}},"summary":"Create user","tags":["user"]}},"/user/createWithList":{"post":{"description":"Creates list of users with given input array","operationId":"createUsersWithListInput","requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/User"},"type":"array"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}},"application/xml":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"Successful operation"},"default":{"description":"successful operation"}},"summary":"Creates list of users with given input array","tags":["user"]}},"/user/login":{"get":{"description":"","operationId":"loginUser","parameters":[{"description":"The user name for login","in":"query","name":"username","schema":{"type":"string"},"style":"form"},{"description":"The password for login in clear text","in":"query","name":"password","schema":{"type":"string"},"style":"form"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"string"}},"application/xml":{"schema":{"type":"string"}}},"description":"successful operation","headers":{"X-Expires-After":{"description":"date in UTC when token expires","schema":{"format":"date-time","type":"string"},"style":"simple"},"X-Rate-Limit":{"description":"calls per hour allowed by the user","schema":{"format":"int32","type":"integer"},"style":"simple"}}},"400":{"description":"Invalid username/password supplied"}},"summary":"Logs user into the system","tags":["user"]}},"/user/logout":{"get":{"description":"","operationId":"logoutUser","responses":{"default":{"description":"successful operation"}},"summary":"Logs out current logged in user session","tags":["user"]}},"/user/{username}":{"delete":{"description":"This can only be done by the logged in user.","operationId":"deleteUser","parameters":[{"description":"The name that needs to be deleted","in":"path","name":"username","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"400":{"description":"Invalid username supplied"},"404":{"description":"User not found"}},"summary":"Delete user","tags":["user"]},"get":{"description":"","operationId":"getUserByName","parameters":[{"description":"The name that needs to be fetched. Use user1 for testing. ","in":"path","name":"username","required":true,"schema":{"type":"string"},"style":"simple"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}},"application/xml":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"successful operation"},"400":{"description":"Invalid username supplied"},"404":{"description":"User not found"}},"summary":"Get user by user name","tags":["user"]},"put":{"description":"This can only be done by the logged in user.","operationId":"updateUser","parameters":[{"description":"name that need to be deleted","in":"path","name":"username","required":true,"schema":{"type":"string"},"style":"simple"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/User"}},"application/xml":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"Update an existent user in the store"},"responses":{"default":{"description":"successful operation"}},"summary":"Update user","tags":["user"]}}},"servers":[{"url":"https://petstore3.swagger.io/api/v3"}],"tags":[{"description":"Everything about your Pets","externalDocs":{"description":"Find out more","url":"http://swagger.io"},"name":"pet"},{"description":"Access to Petstore orders","externalDocs":{"description":"Find out more about our store","url":"http://swagger.io"},"name":"store"},{"description":"Operations about user","name":"user"}]}"### })) .route("/ui", axum::routing::get(|| async move{ axum::response::Html(r###" <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="description" content="SwaggerUI" /> <title>SwaggerUI</title> <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" /> </head> <body> <div id="swagger-ui"></div> <script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script> <script> window.onload = () => { window.ui = SwaggerUIBundle({ url: location.href.replace("/ui","/openapi.json"), dom_id: '#swagger-ui', }); }; </script> </body> </html> "###) })) } pub fn axum_router<S:Server>()->axum::Router{ axum::Router::new() .nest_service("https://petstore3.swagger.io/api/v3", axum_router_operations::<S>()) } use std::env; pub struct TestServer{} impl Server for TestServer{} #[allow(dead_code)] #[tokio::main] async fn main() { let app = axum_router::<TestServer>().layer(axum::extract::DefaultBodyLimit::disable()); let port:u16 = env::var("PORT").unwrap_or("8080".to_string()).parse().expect("PORT should be integer"); println!("http://localhost:{}/api/ui", port); let bind=format!("0.0.0.0:{}", port); let listener = tokio::net::TcpListener::bind(bind).await.unwrap(); axum::serve(listener, app) .with_graceful_shutdown(async { tokio::signal::ctrl_c().await.unwrap() }) .await .unwrap(); }