poem icon indicating copy to clipboard operation
poem copied to clipboard

Would it be possible to generate an openapi description for "newtype" which contain only one field ?

Open szagi3891 opened this issue 2 years ago • 4 comments

Description of the feature

It is quite a useful construction to use newtype to specify e.g. ID. Unfortunately, the current implementation of the Object macro does not allow the generation of an openapi for newtype

error: All fields must be named.
  --> src/main.rs:31:8
   |
31 | struct SportId(String);
   |        ^^^^^^^

error[E0277]: the trait bound `SportId: Type` is not satisfied
  --> src/main.rs:33:35
   |
33 | #[derive(Clone, Debug, PartialEq, Object)]
   |                                   ^^^^^^ the trait `Type` is not implemented for `SportId`
   |
   = help: the following other types implement trait `Type`:
             &'a str
             &T
             &[T]
             A
             Arc<T>
             B
             BTreeMap<K, V>
             BTreeSet<T>
           and 39 others
   = note: this error originates in the derive macro `Object` (in Nightly builds, run with -Z macro-backtrace for more info)

Code example (if possible)

#[derive(Clone, Debug, PartialEq, Object)]
struct SportId(String);

#[derive(Clone, Debug, PartialEq, Object)]
pub struct SportModel {
    pub id: SportId,
    pub name: Arc<String>,
    pub display_order: u64,
    geo_rule_type: GeoRuleType,
}
git clone https://github.com/szagi3891/poem-test
cargo run

szagi3891 avatar Sep 26 '22 12:09 szagi3891

You should need the 'NewType' macro.

https://github.com/poem-web/poem/blob/2d91d10a1f23ef4553e33c7981be7e78f0cd969b/poem-openapi/tests/newtype.rs#L15

sunli829 avatar Oct 19 '22 14:10 sunli829

I tried to do this on a generic type, like this:

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize, NewType)]
#[serde(transparent)]
pub struct JVec<T>(pub Vec<T>);

Unfortunately, that results in lots of compile errors. Should this be supported? For now I have just copied https://github.com/poem-web/poem/blob/master/poem-openapi/src/types/external/vec.rs and changed it to work on the inner Vec, and that works, but it would be nicer if that wasn't necessary. I do understand that parsing generics in derive macros is probably pretty complicated.

miquels avatar Nov 25 '22 11:11 miquels

I tried to do this on a generic type, like this:

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize, NewType)]
#[serde(transparent)]
pub struct JVec<T>(pub Vec<T>);

Unfortunately, that results in lots of compile errors. Should this be supported? For now I have just copied https://github.com/poem-web/poem/blob/master/poem-openapi/src/types/external/vec.rs and changed it to work on the inner Vec, and that works, but it would be nicer if that wasn't necessary. I do understand that parsing generics in derive macros is probably pretty complicated.

I'll make the NewType macro support generics later, for now you can do this: 🙂

type JVec<T> = Vec<T>;

sunli829 avatar Nov 25 '22 12:11 sunli829

Well, it is a newtype specifically because I have implemented other traits on it - traits from the sqlx crate, so that the type can be read/written directly from/to the database. Thanks for the suggestion anyway :)

miquels avatar Nov 25 '22 14:11 miquels