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

Add smallvec support #162

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ts-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ default = ["serde-compat"]
indexmap-impl = ["indexmap"]
ordered-float-impl = ["ordered-float"]
heapless-impl = ["heapless"]
smallvec-impl = ["smallvec"]

[dev-dependencies]
serde = { version = "1.0", features = ["derive"] }
Expand All @@ -42,3 +43,4 @@ url = { version = "2.3", optional = true }
thiserror = "1"
indexmap = { version = "2.0.0", optional = true }
ordered-float = { version = "3.0.0", optional = true }
smallvec = { version = "1.11", optional = true }
96 changes: 51 additions & 45 deletions ts-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,34 +70,34 @@
//! - type aliases must not alias generic types (#70)
//!
//! ## cargo features
//! - `serde-compat` (default)
//! - `serde-compat` (default)
//!
//! Enable serde compatibility. See below for more info.
//! Enable serde compatibility. See below for more info.
//! - `format`
//!
//! When enabled, the generated typescript will be formatted.
//! Currently, this sadly adds quite a bit of dependencies.
//! - `chrono-impl`
//! - `chrono-impl`
//!
//! Implement `TS` for types from chrono
//! - `bigdecimal-impl`
//! Implement `TS` for types from chrono
//! - `bigdecimal-impl`
//!
//! Implement `TS` for types from bigdecimal
//! - `url-impl`
//! Implement `TS` for types from bigdecimal
//! - `url-impl`
//!
//! Implement `TS` for types from url
//! - `uuid-impl`
//! - `uuid-impl`
//!
//! Implement `TS` for types from uuid
//! - `bson-uuid-impl`
//!
//! Implement `TS` for types from bson
//! - `bytes-impl`
//!
//! Implement `TS` for types from bytes
//! - `indexmap-impl`
//! Implement `TS` for types from bytes
//! - `indexmap-impl`
//!
//! Implement `TS` for `IndexMap` and `IndexSet` from indexmap
//! Implement `TS` for `IndexMap` and `IndexSet` from indexmap
//!
//! - `ordered-float-impl`
//!
Expand All @@ -107,6 +107,9 @@
//!
//! Implement `TS` for `Vec` from heapless
//!
//! - `smallvec-impl`
//!
//! Implement `TS` for `SmallVec` from smallvec
//!
//! If there's a type you're dealing with which doesn't implement `TS`, use `#[ts(type = "..")]` or open a PR.
//!
Expand Down Expand Up @@ -160,8 +163,8 @@ pub use crate::export::ExportError;
mod chrono;
mod export;

/// A type which can be represented in TypeScript.
/// Most of the time, you'd want to derive this trait instead of implementing it manually.
/// A type which can be represented in TypeScript.
/// Most of the time, you'd want to derive this trait instead of implementing it manually.
/// ts-rs comes with implementations for all primitives, most collections, tuples,
/// arrays and containers.
///
Expand All @@ -181,69 +184,69 @@ mod export;
/// ### container attributes
/// attributes applicable for both structs and enums
///
/// - `#[ts(export)]`:
/// - `#[ts(export)]`:
/// Generates a test which will export the type, by default to `bindings/<name>.ts` when running
/// `cargo test`
///
/// - `#[ts(export_to = "..")]`:
/// Specifies where the type should be exported to. Defaults to `bindings/<name>.ts`.
/// If the provided path ends in a trailing `/`, it is interpreted as a directory.
/// - `#[ts(export_to = "..")]`:
/// Specifies where the type should be exported to. Defaults to `bindings/<name>.ts`.
/// If the provided path ends in a trailing `/`, it is interpreted as a directory.
/// Note that you need to add the `export` attribute as well, in order to generate a test which exports the type.
///
/// - `#[ts(rename = "..")]`:
/// - `#[ts(rename = "..")]`:
/// Sets the typescript name of the generated type
///
/// - `#[ts(rename_all = "..")]`:
/// - `#[ts(rename_all = "..")]`:
/// Rename all fields/variants of the type.
/// Valid values are `lowercase`, `UPPERCASE`, `camelCase`, `snake_case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, "kebab-case"
///
///
/// ### struct field attributes
///
/// - `#[ts(type = "..")]`:
/// Overrides the type used in TypeScript.
/// This is useful when there's a type for which you cannot derive `TS`.
/// - `#[ts(type = "..")]`:
/// Overrides the type used in TypeScript.
/// This is useful when there's a type for which you cannot derive `TS`.
///
/// - `#[ts(rename = "..")]`:
/// Renames this field
/// - `#[ts(rename = "..")]`:
/// Renames this field
///
/// - `#[ts(inline)]`:
/// Inlines the type of this field
/// - `#[ts(inline)]`:
/// Inlines the type of this field
///
/// - `#[ts(skip)]`:
/// Skip this field
/// - `#[ts(skip)]`:
/// Skip this field
///
/// - `#[ts(optional)]`:
/// - `#[ts(optional)]`:
/// Indicates the field may be omitted from the serialized struct
///
/// - `#[ts(flatten)]`:
/// Flatten this field (only works if the field is a struct)
///
/// - `#[ts(flatten)]`:
/// Flatten this field (only works if the field is a struct)
///
/// ### enum attributes
///
/// - `#[ts(tag = "..")]`:
/// - `#[ts(tag = "..")]`:
/// Changes the representation of the enum to store its tag in a separate field.
/// See [the serde docs](https://serde.rs/enum-representations.html).
///
/// - `#[ts(content = "..")]`:
/// - `#[ts(content = "..")]`:
/// Changes the representation of the enum to store its content in a separate field.
/// See [the serde docs](https://serde.rs/enum-representations.html).
///
/// - `#[ts(untagged)]`:
/// - `#[ts(untagged)]`:
/// Changes the representation of the enum to not include its tag.
/// See [the serde docs](https://serde.rs/enum-representations.html).
///
/// - `#[ts(rename_all = "..")]`:
/// Rename all variants of this enum.
/// - `#[ts(rename_all = "..")]`:
/// Rename all variants of this enum.
/// Valid values are `lowercase`, `UPPERCASE`, `camelCase`, `snake_case`, `PascalCase`, `SCREAMING_SNAKE_CASE`, "kebab-case"
///
///
/// ### enum variant attributes
///
/// - `#[ts(rename = "..")]`:
/// Renames this variant
/// - `#[ts(rename = "..")]`:
/// Renames this variant
///
/// - `#[ts(skip)]`:
/// Skip this variant
/// - `#[ts(skip)]`:
/// Skip this variant
pub trait TS {
const EXPORT_TO: Option<&'static str> = None;

Expand All @@ -267,7 +270,7 @@ pub trait TS {
panic!("{} cannot be inlined", Self::name());
}

/// Flatten an type declaration.
/// Flatten an type declaration.
/// This function will panic if the type cannot be flattened.
fn inline_flattened() -> String {
panic!("{} cannot be flattened", Self::name())
Expand All @@ -279,7 +282,7 @@ pub trait TS {
where
Self: 'static;

/// `true` if this is a transparent type, e.g tuples or a list.
/// `true` if this is a transparent type, e.g tuples or a list.
/// This is used for resolving imports when using the `export!` macro.
fn transparent() -> bool;

Expand All @@ -306,7 +309,7 @@ pub trait TS {
export::export_type_to::<Self, _>(path)
}

/// Manually generate bindings for this type, returning a [`String`].
/// Manually generate bindings for this type, returning a [`String`].
/// This function does not format the output, even if the `format` feature is enabled.
fn export_to_string() -> Result<String, ExportError>
where
Expand Down Expand Up @@ -623,6 +626,9 @@ impl_shadow!(as HashMap<K, V>: impl<K: TS, V: TS> TS for indexmap::IndexMap<K, V
#[cfg(feature = "heapless-impl")]
impl_shadow!(as Vec<T>: impl<T: TS, const N: usize> TS for heapless::Vec<T, N>);

#[cfg(feature = "smallvec-impl")]
impl_shadow!(as Vec<T>: impl<T: TS, const N: usize> TS for smallvec::SmallVec<[T; N]> where [T; N]: smallvec::Array);

#[cfg(feature = "bytes-impl")]
mod bytes {
use super::TS;
Expand Down