Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing utoipa/utoipa-swagger-ui successfully build on Windows and made path proc macro attribute more permissive #830

Merged
merged 6 commits into from
Jan 2, 2024

Conversation

JohnScience
Copy link
Contributor

@JohnScience JohnScience commented Dec 31, 2023

I'm using utoipa for documentation of a custom binary protocol which is used for communication between a server and client applications.

P.S.

Custom content type had to be used because swagger UI does not display examples for content type application/octet-stream.

Allowing utoipa/utoipa-swagger-ui successfully build on Windows

On Windows, \ is a part of path and using it in Rust string makes the following character act as an escape character. For correct behavior on Windows, raw string literal syntax must be used instead.

Allowing any AnyValue for example field

While documenting the web server, I realized that I can use only json! macro an example (and I doubt that this restriction was necessary because the only requirement for the type is that it has to implement serde::se::Serialize). Even though I can use json! macro with a copy-pasted u8 array, it is not ideal.

Currently, my utoipa::path attribute looks like this:

#[utoipa::path(
    post,
    request_body(
        content = ElasticModulesForUnidirectionalCompositeArgsMessage,
        description = "Python struct format string: \"BBxxxxxxddddd\". See <https://docs.python.org/3/library/struct.html#format-strings>.\n\n\
        See schema for the order of the fields (but not their sizes).",
        content_type = "application/x.elastic-modules-for-unidirectional-composite-args-message",
        example = ElasticModulesForUnidirectionalCompositeArgsMessage::example_as_serde_big_array,
    ),
    responses (
        (
            status = 200,
            description = "Computes elastic_modules_for_unidirectional_composite. \
            Returns the binary representation of [E1, E2, E3, nu12, nu13, nu23, G12, G13, G23] with the requested endianness.\n\n\
            Python struct format string: \"ddddddddd\". See <https://docs.python.org/3/library/struct.html#format-strings>.",
            body = ElasticModulesForUnidirectionalCompositeResponseMessage,
            content_type = "application/x.elastic-modules-for-unidirectional-composite-response-message"
        ),
    )
)]
#[post("/compute/elastic_modules_for_unidirectional_composite")]
async fn elastic_modules_for_unidirectional_composite(
    args: ElasticModulesForUnidirectionalCompositeArgsMessage,
) -> impl Responder {
    //...
}

and I'm planning to tinker with utoipa more to have less boilerplate.

@JohnScience
Copy link
Contributor Author

JohnScience commented Dec 31, 2023

Allowed arbitrary expressions to be used in the description field.

Now my path attribute became a bit more maintainable:

#[utoipa::path(
    post,
    request_body(
        content = ElasticModulesForUnidirectionalCompositeArgsMessage,
        description = format!(
            "Python struct format string: {:?}. See <https://docs.python.org/3/library/struct.html#format-strings>.\n\n\
            See schema for the order of the fields (but not their sizes).",
            ElasticModulesForUnidirectionalCompositeArgsMessage::py_struct_format_string()
        ),
        content_type = "application/x.elastic-modules-for-unidirectional-composite-args-message",
        example = ElasticModulesForUnidirectionalCompositeArgsMessage::example_as_serde_big_array,
    ),
    responses (
        (
            status = 200,
            description = "Computes elastic_modules_for_unidirectional_composite. \
            Returns the binary representation of [E1, E2, E3, nu12, nu13, nu23, G12, G13, G23] with the requested endianness.\n\n\
            Python struct format string: \"ddddddddd\". See <https://docs.python.org/3/library/struct.html#format-strings>.",
            body = ElasticModulesForUnidirectionalCompositeResponseMessage,
            content_type = "application/x.elastic-modules-for-unidirectional-composite-response-message"
        ),
    )
)]
#[post("/compute/elastic_modules_for_unidirectional_composite")]
async fn elastic_modules_for_unidirectional_composite(
    args: ElasticModulesForUnidirectionalCompositeArgsMessage,
) -> impl Responder {
    //...
}

However, the change affected only the description of request body. Other fields deserve fair treatment as well.

@JohnScience
Copy link
Contributor Author

JohnScience commented Dec 31, 2023

Updated path:

#[utoipa::path(
    post,
    request_body(
        content = ElasticModulesForUnidirectionalCompositeArgsMessage,
        description = format!(
            "Python struct format string: {:?}. See <https://docs.python.org/3/library/struct.html#format-strings>.\n\n\
            See schema for the order of the fields (but not their sizes).",
            ElasticModulesForUnidirectionalCompositeArgsMessage::py_struct_format_string()
        ),
        content_type = ElasticModulesForUnidirectionalCompositeArgsMessage::content_type(),
        example = ElasticModulesForUnidirectionalCompositeArgsMessage::example_as_serde_big_array,
    ),
    responses (
        (
            status = 200,
            description = "Computes elastic_modules_for_unidirectional_composite. \
            Returns the binary representation of [E1, E2, E3, nu12, nu13, nu23, G12, G13, G23] with the requested endianness.\n\n\
            Python struct format string: \"ddddddddd\". See <https://docs.python.org/3/library/struct.html#format-strings>.",
            body = ElasticModulesForUnidirectionalCompositeResponseMessage,
            content_type = "application/x.elastic-modules-for-unidirectional-composite-response-message"
        ),
    )
)]
#[post("/compute/elastic_modules_for_unidirectional_composite")]
async fn elastic_modules_for_unidirectional_composite(
    args: ElasticModulesForUnidirectionalCompositeArgsMessage,
) -> impl Responder {
    //...
}

@JohnScience
Copy link
Contributor Author

Updated path:

#[utoipa::path(
    post,
    request_body(
        content = ElasticModulesForUnidirectionalCompositeArgsMessage,
        description = format!(
            "Python struct format string: {:?}. See <https://docs.python.org/3/library/struct.html#format-strings>.\n\n\
            See schema for the order of the fields (but not their sizes).",
            ElasticModulesForUnidirectionalCompositeArgsMessage::py_struct_format_string()
        ),
        content_type = ElasticModulesForUnidirectionalCompositeArgsMessage::content_type(),
        example = ElasticModulesForUnidirectionalCompositeArgsMessage::example_as_serde_big_array,
    ),
    responses (
        (
            status = 200,
            description = "Computes elastic_modules_for_unidirectional_composite. \
            Returns the binary representation of [E1, E2, E3, nu12, nu13, nu23, G12, G13, G23] with the requested endianness.\n\n\
            Python struct format string: \"ddddddddd\". See <https://docs.python.org/3/library/struct.html#format-strings>.",
            body = ElasticModulesForUnidirectionalCompositeResponseMessage,
            content_type = ElasticModulesForUnidirectionalCompositeResponseMessage::content_type(),
        ),
    )
)]
#[post("/compute/elastic_modules_for_unidirectional_composite")]
async fn elastic_modules_for_unidirectional_composite(
    args: ElasticModulesForUnidirectionalCompositeArgsMessage,
) -> impl Responder {
    //...
}

@JohnScience
Copy link
Contributor Author

JohnScience commented Dec 31, 2023

#[utoipa::path(
    post,
    request_body(
        content = ElasticModulesForUnidirectionalCompositeArgsMessage,
        description = format!(
            "Python struct format string: {:?}. See <https://docs.python.org/3/library/struct.html#format-strings>.\n\n\
            See schema for the order of the fields (but not their sizes).",
            ElasticModulesForUnidirectionalCompositeArgsMessage::py_struct_format_string()
        ),
        content_type = ElasticModulesForUnidirectionalCompositeArgsMessage::content_type(),
        example = ElasticModulesForUnidirectionalCompositeArgsMessage::example_as_serde_big_array,
    ),
    responses (
        (
            status = 200,
            description = format!(
                "Computes elastic_modules_for_unidirectional_composite. \
                Returns the binary representation of [E1, E2, E3, nu12, nu13, nu23, G12, G13, G23] with the requested endianness.\n\n\
                Python struct format string: {:?}. See <https://docs.python.org/3/library/struct.html#format-strings>.",
                ElasticModulesForUnidirectionalCompositeResponseMessage::py_struct_format_string()
            ),
            body = ElasticModulesForUnidirectionalCompositeResponseMessage,
            content_type = ElasticModulesForUnidirectionalCompositeResponseMessage::content_type(),
        ),
    )
)]
#[post("/compute/elastic_modules_for_unidirectional_composite")]
async fn elastic_modules_for_unidirectional_composite(
    args: ElasticModulesForUnidirectionalCompositeArgsMessage,
) -> impl Responder {
    //...
}

@JohnScience JohnScience changed the title Allowed utoipa/utoipa-swagger-ui successfully build on Windows and allowed any AnyValue for example field Allowing utoipa/utoipa-swagger-ui successfully build on Windows and made path proc macro attribute more permissive Dec 31, 2023
Copy link
Owner

@juhaku juhaku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, this is is a good relaxing of the restrictions of the path macro.

@juhaku juhaku merged commit fe229e2 into juhaku:master Jan 2, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants