ts-rs
ts-rs copied to clipboard
bug: `#[serde(flatten)]` is not working propertly on fields of type `HashMap`
Describe the bug HashMaps should be flattenable
To Reproduce
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, TS)]
pub struct ThirdPartyWidgetSettings {
/// enable or disable the widget
pub enabled: bool,
#[serde(flatten)]
pub rest: HashMap<String, serde_json::Value>,
}
Expected behavior
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { JsonValue } from './serde_json/JsonValue.ts';
export type ThirdPartyWidgetSettings = {
/**
* enable or disable the widget
*/
enabled: boolean;
} & ({ [key in string]?: JsonValue });
Screenshots
test handlers::events::export_bindings_seeleneventpayload ... FAILED
failures:
---- handlers::commands::export_bindings_seelencommandreturn stdout ----
thread 'handlers::commands::export_bindings_seelencommandreturn' panicked at C:\Users\dlmqc\.cargo\git\checkouts\ts-rs-4e1afb5ed402ab6a\30ba9d1\ts-rs\src\lib.rs:944:9:
{ [key in string]?: string } cannot be flattened
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- state::settings::export_bindings_settings stdout ----
thread 'state::settings::export_bindings_settings' panicked at C:\Users\dlmqc\.cargo\git\checkouts\ts-rs-4e1afb5ed402ab6a\30ba9d1\ts-rs\src\lib.rs:944:9:
{ [key in string]?: string } cannot be flattened
---- handlers::commands::export_bindings_seelencommandargument stdout ----
thread 'handlers::commands::export_bindings_seelencommandargument' panicked at C:\Users\dlmqc\.cargo\git\checkouts\ts-rs-4e1afb5ed402ab6a\30ba9d1\ts-rs\src\lib.rs:944:9:
{ [key in string]?: string } cannot be flattened
---- handlers::events::export_bindings_seeleneventpayload stdout ----
thread 'handlers::events::export_bindings_seeleneventpayload' panicked at C:\Users\dlmqc\.cargo\git\checkouts\ts-rs-4e1afb5ed402ab6a\30ba9d1\ts-rs\src\lib.rs:944:9:
{ [key in string]?: string } cannot be flattened
failures:
handlers::commands::export_bindings_seelencommandargument
handlers::commands::export_bindings_seelencommandreturn
handlers::events::export_bindings_seeleneventpayload
state::settings::export_bindings_settings
Version latest
Additional context As a workaround I'm using a enum as wrapper in meantime this is fixed
use schemars::JsonSchema;
/// This struct is intented to work with ts-rs flattening
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, TS)]
#[serde(untagged)]
pub enum Flatenable<T> {
Inner(T),
}
impl<T: Default> Default for Flatenable<T> {
fn default() -> Self {
Flatenable::Inner(T::default())
}
}
impl<T> std::ops::Deref for Flatenable<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Flatenable::Inner(inner) => inner,
}
}
}
impl<T> std::ops::DerefMut for Flatenable<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Flatenable::Inner(inner) => inner,
}
}
}
Now this works fine:
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, TS)]
pub struct ThirdPartyWidgetSettings {
/// enable or disable the widget
pub enabled: bool,
#[serde(flatten)]
pub rest: Flatenable<HashMap<String, serde_json::Value>>,
}