FromJsonQueryResult should also work with generic types
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 9.9k
- Forks
- 734
- Avg merge
- 6h 36m
- Merged PRs (30d)
- 8
Description
Description
FromJsonQueryResult currently doesn't work with generics. This is useful to e. g. wrap a Vec<T> in a custom type List<T>(Vec<T>) that implements the required traits to be used in SeaORM.
This is caused by the FromJsonQueryResult currently ignoring any generics.
This can be fixed with these changes to expand_derive_from_json_query_result and derive_from_json_query_result:
- replace all occurances of
implwithimpl #genericswhere#genericscomes from the parsed macro input - replace all occurances of
#identwith#ident_with_genericswhere#ident_with_genericsis theidentfollowed by the generic paramters with their trait bounds removed - add trait bounds
where #ident_with_generics: Serializeandwhere #ident_with_generics: DeserializeOwnedwhere required (see workaround below)
Steps to Reproduce
cargo new test-projectcd test-projectcargo add sea-ormcargo add serde -F derivecargo add serde_json- Paste this code into
src/main.rs
use sea_orm::{prelude::*, FromJsonQueryResult};
use serde::{Deserialize, Serialize};
[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize, FromJsonQueryResult)]
#[serde(transparent)]
pub struct List<T>(pub Vec<T>);
Expected Behavior
compiles without errors
Actual Behavior
error[E0107]: missing generics for struct `List`
--> src/main.rs:16:12
|
16 | pub struct List<T>(pub Vec<T>);
| ^^^^ expected 1 generic argument
|
note: struct defined here, with 1 generic parameter: `T`
--> src/main.rs:16:12
|
16 | pub struct List<T>(pub Vec<T>);
| ^^^^ -
help: add missing generic argument
|
16 | pub struct List<T><T>(pub Vec<T>);
| +++
Reproduces How Often
Is it always reproducible? -> Yes
Workarounds
manually implement the derived traits:
[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
#[serde(transparent)]
pub struct List<T>(pub Vec<T>);
impl<T> sea_orm::TryGetableFromJson for List<T> where for<'de> T: Deserialize<'de> {}
impl<T> std::convert::From<List<T>> for sea_orm::Value
where
List<T>: Serialize,
{
fn from(source: List<T>) -> Self {
sea_orm::Value::Json(
serde_json::to_value(&source)
.ok()
.map(|s| std::boxed::Box::new(s)),
)
}
}
impl<T> sea_orm::sea_query::ValueType for List<T>
where
List<T>: DeserializeOwned,
{
fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
match v {
sea_orm::Value::Json(Some(json)) => {
Ok(serde_json::from_value(*json).map_err(|_| sea_orm::sea_query::ValueTypeErr)?)
}
_ => Err(sea_orm::sea_query::ValueTypeErr),
}
}
fn type_name() -> String {
stringify!(#ident).to_owned()
}
fn array_type() -> sea_orm::sea_query::ArrayType {
sea_orm::sea_query::ArrayType::Json
}
fn column_type() -> sea_orm::sea_query::ColumnType {
sea_orm::sea_query::ColumnType::Json
}
}
impl<T> sea_orm::sea_query::Nullable for List<T> {
fn null() -> sea_orm::Value {
sea_orm::Value::Json(None)
}
}
Reproducible Example
[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize, FromJsonQueryResult)]
#[serde(transparent)]
pub struct List<T>(pub Vec<T>);
Versions
❯ cargo tree | grep sea-
├── sea-orm v0.12.10
│ ├── sea-orm-macros v0.12.10 (proc-macro)
│ │ ├── sea-bae v0.2.0 (proc-macro)
│ ├── sea-query v0.30.6
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with expand_derive_from_json_query_result in sea-orm-macros/src/derives/try_getable_from_json.rs and derive_from_json_query_result in sea-orm-macros/src/lib.rs. Reproduce the issue using the generic List example and inspect how parsed generics are handled. Done means the example compiles with FromJsonQueryResult and the generated implementations preserve the required serialization and deserialization bounds.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100