Skip to content

Commit

Permalink
Chore update docs and REAMDEs (#42)
Browse files Browse the repository at this point in the history
* Add xml objects docs
* Update docs in various places like utoipa, utoipa-gen.
  * Now there is a better documentation for actix_extras feature use and use of Rust's own #[deprecated] attribute.
* Update READMEs for utoipa and utoipa-swagger-ui
  • Loading branch information
juhaku authored Mar 13, 2022
1 parent 613301e commit 0e54a12
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 7 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ framework. All functionalities are not restricted to any specific framework.

## What's up with the word play?

The name comes from words `utopic` and `api` where `uto` is the first three letters of utopic
and the `ipa` is api reversed.
The name comes from words `utopic` and `api` where `uto` is the first three letters of _utopic_
and the `ipa` is _api_ reversed.

## Features

* **default** Default enabled features are **json**.
* **json** Enables **serde_json** what allow to use json values in OpenAPI specification values. Thus is
enabled by default.
* **actix_extras** Enhances actix-web intgration with being able to parse some documentation
from actix web macro attributes and types.
from actix web macro attributes and types. See the [path attribute macro](https://docs.rs/utoipa/0.1.0-beta6/utoipa/attr.path.html) for more details.
* **debug** Add extra traits such as debug traits to openapi definitions and elsewhere.

## Install
Expand Down Expand Up @@ -211,7 +211,7 @@ This would produce api doc something similar to:

* See how to serve OpenAPI doc via Swagger UI check [utoipa-swagger-ui](https://docs.rs/utoipa-swagger-ui/) crate for more details.
* Browse to [examples](https://github.com/juhaku/utoipa/tree/master/examples) for more comprehensinve examples.
* Modify generated OpenAPI at runtime check `Modify` trait for more details.
* Modify generated OpenAPI at runtime check [Modify](https://docs.rs/utoipa/0.1.0-beta6/utoipa/trait.Modify.html) trait for more details.
* More about OpenAPI security in [security documentation](https://docs.rs/utoipa/0.1.0-beta6/utoipa/openapi/security/index.html).

# License
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
//! * **json** Enables **serde_json** what allow to use json values in OpenAPI specification values.
//! Thus is enabled by default.
//! * **actix_extras** Enhances actix-web intgration with being able to parse some documentation
//! from actix web macro attributes and types.
//! from actix web macro attributes and types. See [`utoipa::path(...)`][path] for more details.
//! * **debug** Add extra traits such as debug traits to openapi definitions and elsewhere.
//!
//! # Install
Expand Down Expand Up @@ -154,6 +154,8 @@
//! * Modify generated OpenAPI at runtime check [`Modify`] trait for more details.
//! * More about OpenAPI security in [security documentation][security].
//!
//! [path]: attr.path.html
//!
//! [security]: openapi/security/index.html
/// Rust implementation of Openapi Spec V3
Expand Down
4 changes: 3 additions & 1 deletion src/openapi/security.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! OpenAPI schema's security components implementations.
//! Implements [OpenAPI Security Schema][security] types.
//!
//! Refer to [`SecuritySchema`] for usage and more details.
//!
//! [security]: https://spec.openapis.org/oas/latest.html#security-scheme-object
use std::{collections::HashMap, iter};

use serde::{Deserialize, Serialize};
Expand Down
36 changes: 36 additions & 0 deletions src/openapi/xml.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,93 @@
//! Implements [OpenAPI Xml Object][xml_object] types.
//!
//! [xml_object]: https://spec.openapis.org/oas/latest.html#xml-object
use std::borrow::Cow;

use serde::{Deserialize, Serialize};

/// Implements [OpenAPI Xml Object][xml_object].
///
/// Can be used to modify xml output format of specific [OpenAPI Schema Object][schema_object] which are
/// implemented in [`schema`][schema] module.
///
/// [xml_object]: https://spec.openapis.org/oas/latest.html#xml-object
/// [schema_object]: https://spec.openapis.org/oas/latest.html#schema-object
/// [schema]: ../schema/index.html
#[non_exhaustive]
#[derive(Serialize, Deserialize, Default, Clone)]
#[cfg_attr(feature = "debug", derive(Debug))]
pub struct Xml {
/// Used to replace the name of attribute or type used in schema property.
/// When used with [`Xml::wrapped`] attribute the name will be used as a wrapper name
/// for wrapped array instead of the item or type name.
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<Cow<'static, str>>,

/// Valid uri definition of namespace used in xml.
#[serde(skip_serializing_if = "Option::is_none")]
pub namespace: Option<Cow<'static, str>>,

/// Prefix for xml element [`Xml::name`].
#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<Cow<'static, str>>,

/// Flag deciding will this attribute translate to element attribute instead of xml element.
#[serde(skip_serializing_if = "Option::is_none")]
pub attribute: Option<bool>,

/// Flag only usable with array definition. If set to true the ouput xml will wrap the array of items
/// `<pets><pet></pet></pets>` instead of unwrapped `<pet></pet>`.
#[serde(skip_serializing_if = "Option::is_none")]
pub wrapped: Option<bool>,
}

impl Xml {
/// Construct a new [`Xml`] object.
pub fn new() -> Self {
Self {
..Default::default()
}
}

/// Add [`Xml::name`] to xml object.
///
/// Builder style chainable consuming add name method.
pub fn name<S: Into<Cow<'static, str>>>(mut self, name: Option<S>) -> Self {
self.name = name.map(|name| name.into());

self
}

/// Add [`Xml::namespace`] to xml object.
///
/// Builder style chainable consuming add namespace method.
pub fn namespace<S: Into<Cow<'static, str>>>(mut self, namespace: Option<S>) -> Self {
self.namespace = namespace.map(|namespace| namespace.into());

self
}

/// Add [`Xml::prefix`] to xml object.
///
/// Builder style chainable consuming add prefix method.
pub fn prefix<S: Into<Cow<'static, str>>>(mut self, prefix: Option<S>) -> Self {
self.prefix = prefix.map(|prefix| prefix.into());

self
}

/// Mark [`Xml`] object as attribute. See [`Xml::attribute`]
///
/// Builder style chainable consuming add attribute method.
pub fn attribute(mut self, attribute: Option<bool>) -> Self {
self.attribute = attribute;

self
}

/// Mark [`Xml`] object wrapped. See [`Xml::wrapped`]
///
/// Builder style chainable consuming add wrapped method.
pub fn wrapped(mut self, wrapped: Option<bool>) -> Self {
self.wrapped = wrapped;

Expand Down
1 change: 1 addition & 0 deletions utoipa-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ lazy_static = { version = "1.4", optional = true }
[dev-dependencies]
utoipa = { path = ".." }
serde_json = "1"
actix-web = { version = "3.3" }


[features]
Expand Down
108 changes: 107 additions & 1 deletion utoipa-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ use crate::path::{Path, PathAttr, PathOperation};
/// at item level or field level in struct and enums. Currently placing this attribute to unnamed field does
/// not have any effect.
///
/// You can use the Rust's own `#[deprecated]` attribute on any struct, emun or field to mark it as deprecated and it will
/// reflect to the generated OpenAPI spec.
///
/// `#[deprecated]` attribute supports adding addtional details such as a reason and or since version but this is is not supported in
/// OpenAPI. OpenAPI has only a boolean flag to determine deprecation. While it is totally okay to declare deprecated with reason
/// `#[deprecated = "There is better way to do this"]` the reason would not render in OpenAPI spec.
///
/// # Struct Optional Configuration Options
/// * **example** Can be either `json!(...)` or literal string that can be parsed to json. `json!`
/// should be something that `serde_json::json!` can parse as a `serde_json::Value`. [^json]
/// * **xml** Can be used to define [`Xml`][xml] object properties applicable to Structs.
///
/// [^json]: **json** feature need to be enabled for `json!(...)` type to work.
///
Expand All @@ -61,9 +69,21 @@ use crate::path::{Path, PathAttr, PathOperation};
/// the type of the property according OpenApi spec.
/// * **write_only** Defines property is only used in **write** operations *POST,PUT,PATCH* but not in *GET*
/// * **read_only** Defines property is only used in **read** operations *GET* but not in *POST,PUT,PATCH*
/// * **xml** Can be used to define [`Xml`][xml] object properties applicable to named fields.
///
/// [^json2]: Values are converted to string if **json** feature is not enabled.
///
/// # Xml attribute Configuration Options
///
/// * `xml(name = "...")` Will set name for property or type.
/// * `xml(namespace = "...")` Will set namespace for xml element which needs to be valid uri.
/// * `xml(prefix = "...")` Will set prefix for name.
/// * `xml(attribute)` Will translate property to xml attribute instead of xml element.
/// * `xml(wrapped)` Will make wrapped xml element.
/// * `xml(wrapped(name = "wrap_name"))` Will override the wrapper elements name.
///
/// See [`Xml`][xml] for more details.
///
/// # Examples
///
/// Example struct with struct level example.
Expand Down Expand Up @@ -131,8 +151,41 @@ use crate::path::{Path, PathAttr, PathOperation};
/// }
/// }
/// ```
///
/// Use `xml` attribute to manipulate xml output.
/// ```rust
/// # use utoipa::Component;
/// #[derive(Component)]
/// #[component(xml(name = "user", prefix = "u", namespace = "https://user.xml.schema.test"))]
/// struct User {
/// #[component(xml(attribute, prefix = "u"))]
/// id: i64,
/// #[component(xml(name = "user_name", prefix = "u"))]
/// username: String,
/// #[component(xml(wrapped(name = "linkList"), name = "link"))]
/// links: Vec<String>,
/// #[component(xml(wrapped, name = "photo_url"))]
/// photos_urls: Vec<String>
/// }
/// ```
///
/// Use of Rust's own `#[deprecated]` attribute will reflect to generated OpenAPI spec.
/// ```rust
/// # use utoipa::Component;
/// #[derive(Component)]
/// #[deprecated]
/// struct User {
/// id: i64,
/// username: String,
/// links: Vec<String>,
/// #[deprecated]
/// photos_urls: Vec<String>
/// }
/// ```
///
/// [c]: trait.Component.html
/// [format]: schema/enum.ComponentFormat.html
/// [format]: openapi/schema/enum.ComponentFormat.html
/// [xml]: openapi/xml/struct.Xml.html
pub fn derive_component(input: TokenStream) -> TokenStream {
let DeriveInput {
attrs,
Expand All @@ -154,6 +207,13 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
/// This is a `#[derive]` implementation for [`Path`][path] trait. Macro accepts set of attributes that can
/// be used to configure and override default values what are resolved automatically.
///
/// You can use the Rust's own `#[deprecated]` attribute on functions to mark it as deprecated and it will
/// reflect to the generated OpenAPI spec. Only **parameters** has a special **deprecated** attribute to define them as deprecated.
///
/// `#[deprecated]` attribute supports adding addtional details such as a reason and or since version but this is is not supported in
/// OpenAPI. OpenAPI has only a boolean flag to determine deprecation. While it is totally okay to declare deprecated with reason
/// `#[deprecated = "There is better way to do this"]` the reason would not render in OpenAPI spec.
///
/// # Path Attributes
///
/// * **operation** _**Must be first parameter!**_ Accepted values are known http operations suchs as
Expand All @@ -169,6 +229,10 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
/// * **params** Slice of params that the endpoint accepts.
/// * **security** List of [`SecurityRequirement`][security]s local to the path operation.
///
/// > **Note!** when **actix_extras** feature is enabled the **operation** and **path** declaration may be omitted since they
/// > are resolved from **actix-web** attributes. Also **params** may leave the **type** definition out since it will be derived from
/// > function arguments. See the example in examples section.
///
/// # Request Body Attributes
///
/// * **content** Can be used to define the content object. Should be an identifier, slice or option
Expand Down Expand Up @@ -338,12 +402,54 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
/// }
/// ```
///
/// With **actix_extras** feature enabled the you can leave out definitions for **path**, **operation** and **parmater types** [^actix_extras].
/// ```rust
/// use actix_web::{get, web, HttpResponse, Responder};
/// use serde_json::json;
///
/// /// Get Pet by id
/// #[utoipa::path(
/// responses = [
/// (status = 200, description = "Pet found from database")
/// ],
/// params = [
/// ("id", description = "Pet id"),
/// ]
/// )]
/// #[get("/pet/{id}")]
/// async fn get_pet_by_id(web::Path(id): web::Path<i32>) -> impl Responder {
/// HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id) }))
/// }
/// ```
///
/// Use of Rust's own `#[deprecated]` attribute will refect to the generated OpenAPI spec and mark this operation as deprecated.
/// ```rust
/// # use actix_web::{get, web, HttpResponse, Responder};
/// # use serde_json::json;
/// #[utoipa::path(
/// responses = [
/// (status = 200, description = "Pet found from database")
/// ],
/// params = [
/// ("id", description = "Pet id"),
/// ]
/// )]
/// #[get("/pet/{id}")]
/// #[deprecated]
/// async fn get_pet_by_id(web::Path(id): web::Path<i32>) -> impl Responder {
/// HttpResponse::Ok().json(json!({ "pet": format!("{:?}", &id) }))
/// }
/// ```
///
/// [path]: trait.Path.html
/// [openapi]: derive.OpenApi.html
/// [security]: openapi/security/struct.SecurityRequirement.html
/// [security_schema]: openapi/security/struct.SecuritySchema.html
/// [primitive]: https://doc.rust-lang.org/std/primitive/index.html
///
/// [^json]: **json** feature need to be enabled for `json!(...)` type to work.
///
/// [^actix_extras]: **actix_extras** feature need to be enabled and **actix-web** framework must be declared in your `Cargo.toml`.
pub fn path(attr: TokenStream, item: TokenStream) -> TokenStream {
let mut path_attribute = syn::parse_macro_input!(attr as PathAttr);
let ast_fn = syn::parse::<ItemFn>(item).unwrap_or_abort();
Expand Down
4 changes: 4 additions & 0 deletions utoipa-swagger-ui/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# utoipa-swagger-ui

[![Utoipa build](https://github.com/juhaku/utoipa/actions/workflows/build.yaml/badge.svg)](https://github.com/juhaku/utoipa/actions/workflows/build.yaml)
[![crates.io](https://img.shields.io/static/v1?label=crates.io&message=0.1.0-beta1&color=orange&logo=rust)](https://crates.io/crates/utoipa/0.1.0-beta6)
[![docs.rs](https://img.shields.io/static/v1?label=docs.rs&message=utoipa-swagger-ui&color=blue&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K)](https://docs.rs/utoipa-swagger-ui/0.1.0-beta1/utoipa_swagger_ui/)

This crate implements necessary boiler plate code to serve Swagger UI via web server. It
works as a bridge for serving the OpenAPI documetation created with
[utoipa](https://docs.rs/utoipa/) libarary in the Swagger UI.
Expand Down

0 comments on commit 0e54a12

Please sign in to comment.