Repository: Aleph-Alpha/ts-rs
Pull request #350 (2024-09-05 18:41:45)

feature: support smol_str
## Goal
Add support for the widely used string crate `smol_str` ([15m downloads from crates.io](https://crates.io/crates/smol_str)). 
The main and only type in the crate is `SmolStr` which is essentially a string with some optimisations.


## Checklist

- [x] I have followed the steps listed in the [Contributing guide](https://github.com/Aleph-Alpha/ts-rs/blob/main/CONTRIBUTING.md).
- [x] If necessary, I have added documentation related to the changes made.
- [x] I have added or updated the tests related to the changes made.


gustavo-shigueo: Hi @corvusrabus, thanks for the PR! Can you add a quick test for it please? That'll help avoid regressions in the future
corvusrabus: Thanks @gustavo-shigueo. Sure I can do that but I don't see tests for any of the other similar fundamental datatypes like `uuid-impl`, `bigdecimal-impl`,  ... either. Is it necessary?
gustavo-shigueo: I wouldn't say it's necessary, but I do think it's a good idea. Also, thanks for pointing out those missing tests! I'll try to find some time to add them in the weekend
corvusrabus: @gustavo-shigueo. I'll add them if you haven't done it yet
corvusrabus: Added tests @gustavo-shigueo 
gustavo-shigueo: Awesome! Thank you so much @corvusrabus 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1bf7614..9ac7fe9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 - The `bson-uuid-impl` feature now supports `bson::oid::ObjectId` as well ([#340](https://github.com/Aleph-Alpha/ts-rs/pull/340))
 - Allow multile types to have the same `#[ts(export_to = "...")]` attribute and be exported to the same file ([#316](https://github.com/Aleph-Alpha/ts-rs/pull/316))
+- Add support for types from `smol_str` behind cargo feature `smol_str-impl`
 
 ### Fixes
 
diff --git a/Cargo.lock b/Cargo.lock
index ace8028..002a63e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -126,6 +126,15 @@ dependencies = [
  "wyz",
 ]
 
+[[package]]
+name = "borsh"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed"
+dependencies = [
+ "cfg_aliases",
+]
+
 [[package]]
 name = "bson"
 version = "2.11.0"
@@ -180,6 +189,12 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
 [[package]]
 name = "chrono"
 version = "0.4.38"
@@ -828,6 +843,16 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "smol_str"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66eaf762c5af19db3108300515c8aa7a50efc90ff745f4c62288052ebf9fdd25"
+dependencies = [
+ "borsh",
+ "serde",
+]
+
 [[package]]
 name = "stable_deref_trait"
 version = "1.2.0"
@@ -1156,6 +1181,7 @@ dependencies = [
  "semver",
  "serde",
  "serde_json",
+ "smol_str",
  "thiserror",
  "ts-rs-macros",
  "url",
diff --git a/README.md b/README.md
index ccd8715..b840f46 100644
--- a/README.md
+++ b/README.md
@@ -86,6 +86,7 @@ When running `cargo test`, the TypeScript bindings will be exported to the file
 | ordered-float-impl | Implement `TS` for types from *ordered_float*                                                                                                                                                             |
 | heapless-impl      | Implement `TS` for types from *heapless*                                                                                                                                                                  |
 | semver-impl        | Implement `TS` for types from *semver*                                                                                                                                                                    |
+| smol_str-impl      | Implement `TS` for types from *smol_str*                                                                                                                                                                    |
 
 <br/>
 
diff --git a/ts-rs/Cargo.toml b/ts-rs/Cargo.toml
index 1b994ec..8da5e7c 100644
--- a/ts-rs/Cargo.toml
+++ b/ts-rs/Cargo.toml
@@ -31,6 +31,7 @@ indexmap-impl = ["indexmap"]
 ordered-float-impl = ["ordered-float"]
 heapless-impl = ["heapless"]
 semver-impl = ["semver"]
+smolstr-impl = ["smol_str"]
 serde-json-impl = ["serde_json"]
 no-serde-warnings = ["ts-rs-macros/no-serde-warnings"]
 import-esm = []
@@ -53,6 +54,7 @@ bson = { version = "2", optional = true }
 bytes = { version = "1", optional = true }
 url = { version = "2", optional = true }
 semver = { version = "1", optional = true }
+smol_str = { version = "0.3", optional = true  }
 thiserror = "1"
 indexmap = { version = "2", optional = true }
 ordered-float = { version = ">= 3, < 5", optional = true }
diff --git a/ts-rs/src/lib.rs b/ts-rs/src/lib.rs
index 2f7b19c..5e1ccfd 100644
--- a/ts-rs/src/lib.rs
+++ b/ts-rs/src/lib.rs
@@ -84,6 +84,7 @@
 //! | ordered-float-impl | Implement `TS` for types from *ordered_float*                                                                                                                                                             |
 //! | heapless-impl      | Implement `TS` for types from *heapless*                                                                                                                                                                  |
 //! | semver-impl        | Implement `TS` for types from *semver*                                                                                                                                                                    |
+//! | smol_str-impl      | Implement `TS` for types from *smol_str*                                                                                                                                                                    |
 //!
 //! <br/>
 //!
@@ -994,6 +995,9 @@ impl_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
 #[cfg(feature = "bigdecimal-impl")]
 impl_primitives! { bigdecimal::BigDecimal => "string" }
 
+#[cfg(feature = "smolstr-impl")]
+impl_primitives! { smol_str::SmolStr => "string" }
+
 #[cfg(feature = "uuid-impl")]
 impl_primitives! { uuid::Uuid => "string" }
 


Test patch:
diff --git a/ts-rs/tests/integration/impl_primitive.rs b/ts-rs/tests/integration/impl_primitive.rs
new file mode 100644
index 0000000..893439b
--- /dev/null
+++ b/ts-rs/tests/integration/impl_primitive.rs
@@ -0,0 +1,106 @@
+#[cfg(feature = "bigdecimal-impl")]
+#[test]
+fn impl_primitive_bigdecimal() {
+    assert_eq!(
+        <bigdecimal::BigDecimal as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <bigdecimal::BigDecimal as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    )
+}
+
+#[cfg(feature = "smolstr-impl")]
+#[test]
+fn impl_primitive_smolstr() {
+    assert_eq!(
+        <smol_str::SmolStr as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <smol_str::SmolStr as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    )
+}
+
+#[cfg(feature = "uuid-impl")]
+#[test]
+fn impl_primitive_uuid() {
+    assert_eq!(
+        <uuid::Uuid as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <uuid::Uuid as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    )
+}
+
+#[cfg(feature = "url-impl")]
+#[test]
+fn impl_primitive_url() {
+    assert_eq!(
+        <url::Url as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <url::Url as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    )
+}
+
+#[cfg(feature = "ordered-float-impl")]
+#[test]
+fn impl_primitive_order_float() {
+    assert_eq!(
+        <ordered_float::OrderedFloat<f64> as ts_rs::TS>::name(),
+        <f64 as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <ordered_float::OrderedFloat<f64> as ts_rs::TS>::inline(),
+        <f64 as ts_rs::TS>::inline()
+    );
+    assert_eq!(
+        <ordered_float::OrderedFloat<f32> as ts_rs::TS>::name(),
+        <f32 as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <ordered_float::OrderedFloat<f32> as ts_rs::TS>::inline(),
+        <f32 as ts_rs::TS>::inline()
+    )
+}
+
+#[cfg(feature = "bson-uuid-impl")]
+#[test]
+fn impl_primitive_bson_uuid() {
+    assert_eq!(
+        <bson::oid::ObjectId as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <bson::oid::ObjectId as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    );
+    assert_eq!(
+        <bson::Uuid as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <bson::Uuid as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    )
+}
+
+#[cfg(feature = "semver-impl")]
+#[test]
+fn impl_primitive_semver() {
+    assert_eq!(
+        <semver::Version as ts_rs::TS>::name(),
+        <String as ts_rs::TS>::name()
+    );
+    assert_eq!(
+        <semver::Version as ts_rs::TS>::inline(),
+        <String as ts_rs::TS>::inline()
+    )
+}
diff --git a/ts-rs/tests/integration/main.rs b/ts-rs/tests/integration/main.rs
index e1ce0e0..05c3234 100644
--- a/ts-rs/tests/integration/main.rs
+++ b/ts-rs/tests/integration/main.rs
@@ -20,6 +20,7 @@ mod generics;
 mod generics_flatten;
 mod hashmap;
 mod hashset;
+mod impl_primitive;
 mod imports;
 mod indexmap;
 mod infer_as;