From a8fd3e8fbe6e13ababf3ad902c80b5708335b221 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Fri, 11 Jul 2025 16:31:21 -0700 Subject: [PATCH 1/7] Add TryFrom implementations used in Spector tests --- Cargo.lock | 343 ++++++++++++++++-- sdk/typespec/typespec_client_core/Cargo.toml | 1 + .../src/http/request/mod.rs | 257 ++++++++++++- 3 files changed, 567 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 685cb51fa2..11d5d35453 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -17,6 +17,17 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -91,6 +102,12 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-compression" version = "0.4.25" @@ -134,7 +151,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -145,7 +162,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -230,7 +247,7 @@ dependencies = [ "flate2", "futures", "rand 0.9.1", - "rand_chacha", + "rand_chacha 0.9.0", "reqwest", "serde", "serde_json", @@ -252,7 +269,7 @@ dependencies = [ "azure_core_test", "proc-macro2", "quote", - "syn", + "syn 2.0.104", "tokio", ] @@ -317,7 +334,7 @@ dependencies = [ "criterion", "futures", "rand 0.9.1", - "rand_chacha", + "rand_chacha 0.9.0", "rustc_version", "tokio", "tracing", @@ -464,6 +481,18 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -473,12 +502,57 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "bumpalo" version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bytes" version = "1.10.1" @@ -538,6 +612,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "ciborium" version = "0.2.2" @@ -596,7 +676,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -773,7 +853,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.104", ] [[package]] @@ -784,7 +864,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -805,7 +885,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -827,7 +907,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1019,6 +1099,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.31" @@ -1075,7 +1161,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1159,6 +1245,15 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.15.4" @@ -1422,7 +1517,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.4", "serde", ] @@ -1671,7 +1766,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1793,7 +1888,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -1866,6 +1961,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.95" @@ -1875,6 +1979,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quick-xml" version = "0.31.0" @@ -1900,12 +2024,20 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", "serde", ] @@ -1916,10 +2048,20 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.3", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -1936,6 +2078,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ + "getrandom 0.2.16", "serde", ] @@ -2021,6 +2164,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.12.22" @@ -2079,6 +2231,51 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.37.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b203a6425500a03e0919c42d3c47caca51e79f1132046626d2c8871c5092035d" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.25" @@ -2203,6 +2400,12 @@ version = "3.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "584e070911c7017da6cb2eb0788d09f43d789029b5877d3e5ecc8acf86ceee21" +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "security-framework" version = "2.11.1" @@ -2283,7 +2486,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2303,7 +2506,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2326,7 +2529,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2372,7 +2575,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2416,6 +2619,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.10" @@ -2456,6 +2665,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.104" @@ -2484,9 +2704,15 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tar" version = "0.4.44" @@ -2536,7 +2762,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2547,7 +2773,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2611,6 +2837,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.45.1" @@ -2636,7 +2877,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2683,6 +2924,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.5.2" @@ -2747,7 +3005,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2797,7 +3055,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -2837,6 +3095,7 @@ dependencies = [ "quick-xml", "rand 0.9.1", "reqwest", + "rust_decimal", "serde", "serde_json", "time", @@ -2859,7 +3118,7 @@ dependencies = [ "rustc_version", "serde", "serde_json", - "syn", + "syn 2.0.104", "tokio", "typespec_client_core", ] @@ -3000,7 +3259,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -3035,7 +3294,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3272,6 +3531,15 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +[[package]] +name = "winnow" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.39.0" @@ -3287,6 +3555,15 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "yoke" version = "0.8.0" @@ -3307,7 +3584,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", "synstructure", ] @@ -3328,7 +3605,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] @@ -3348,7 +3625,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", "synstructure", ] @@ -3388,7 +3665,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.104", ] [[package]] diff --git a/sdk/typespec/typespec_client_core/Cargo.toml b/sdk/typespec/typespec_client_core/Cargo.toml index a9396c1403..e687805b32 100644 --- a/sdk/typespec/typespec_client_core/Cargo.toml +++ b/sdk/typespec/typespec_client_core/Cargo.toml @@ -20,6 +20,7 @@ pin-project.workspace = true quick-xml = { workspace = true, optional = true } rand.workspace = true reqwest = { workspace = true, optional = true } +rust_decimal = "1.37.2" serde.workspace = true serde_json.workspace = true time.workspace = true diff --git a/sdk/typespec/typespec_client_core/src/http/request/mod.rs b/sdk/typespec/typespec_client_core/src/http/request/mod.rs index dc38355600..91fc9025f1 100644 --- a/sdk/typespec/typespec_client_core/src/http/request/mod.rs +++ b/sdk/typespec/typespec_client_core/src/http/request/mod.rs @@ -13,10 +13,14 @@ use crate::{ Method, Url, }, json::to_json, + time::OffsetDateTime, }; use bytes::Bytes; use serde::Serialize; -use std::{fmt, marker::PhantomData, str::FromStr}; +use serde_json::Value; +use std::{fmt, collections::HashMap, marker::PhantomData, str::FromStr}; +use rust_decimal::Decimal; +use time::format_description::well_known::Rfc3339; /// An HTTP Body. #[derive(Clone)] @@ -291,6 +295,257 @@ impl TryFrom<&'static str> for RequestContent { } } +impl TryFrom for RequestContent { + type Error = crate::Error; + fn try_from(body: Value) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom for RequestContent { + type Error = crate::Error; + fn try_from(body: bool) -> Result { + Ok(Self { + body: Bytes::from(body.to_string()).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Option) -> Result { + Ok(Self { + body: Bytes::from(body.map(|d| d.to_string()).unwrap_or_default()).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!("[{}]", body.iter().map(|b| b.to_string()).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!(r#"["{}"]"#, body.iter().map(|dt| + if let Ok(formatted) = dt.format(&Rfc3339) { + formatted.to_string() + } else { + dt.to_string() + }).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!(r#"[{}]"#, body.iter().map(|s| format!(r#""{}""#, s)).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec<&str>) -> Result { + Ok(Self { + body: Bytes::from(format!(r#"[{}]"#, body.iter().map(|s| format!(r#""{}""#, s)).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!("[{}]", body.iter().map(|f| f.to_string()).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!("[{}]", body.iter().map(|f| f.to_string()).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!("[{}]", body.iter().map(|i| i.to_string()).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(format!("[{}]", body.iter().map(|i| i.to_string()).collect::>().join(","))).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":{}"#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| { + if let Ok(formatted) = v.format(&Rfc3339) { + format!(r#""{}":"{}""#, k, formatted) + } else { + format!(r#""{}":"{}""#, k, v.to_string()) + } + }) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":"{}""#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":{}"#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":{}"#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":{}"#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":{}"#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + +impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_str = body + .into_iter() + .map(|(k, v)| format!(r#""{}":{}"#, k, v)) + .collect::>() + .join(","); + Ok(Self { + body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + phantom: PhantomData, + }) + } +} + impl FromStr for RequestContent { type Err = crate::Error; fn from_str(body: &str) -> Result { From 108b5f8b657311be1e2a87f6c34a8b13afc9e7c4 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Mon, 14 Jul 2025 13:57:58 -0700 Subject: [PATCH 2/7] Format --- .../src/http/request/mod.rs | 85 +++++++++++++++---- 1 file changed, 70 insertions(+), 15 deletions(-) diff --git a/sdk/typespec/typespec_client_core/src/http/request/mod.rs b/sdk/typespec/typespec_client_core/src/http/request/mod.rs index 91fc9025f1..9e49a4fa09 100644 --- a/sdk/typespec/typespec_client_core/src/http/request/mod.rs +++ b/sdk/typespec/typespec_client_core/src/http/request/mod.rs @@ -16,10 +16,10 @@ use crate::{ time::OffsetDateTime, }; use bytes::Bytes; +use rust_decimal::Decimal; use serde::Serialize; use serde_json::Value; -use std::{fmt, collections::HashMap, marker::PhantomData, str::FromStr}; -use rust_decimal::Decimal; +use std::{collections::HashMap, fmt, marker::PhantomData, str::FromStr}; use time::format_description::well_known::Rfc3339; /// An HTTP Body. @@ -329,7 +329,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!("[{}]", body.iter().map(|b| b.to_string()).collect::>().join(","))).into(), + body: Bytes::from(format!( + "[{}]", + body.iter() + .map(|b| b.to_string()) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -339,12 +346,18 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!(r#"["{}"]"#, body.iter().map(|dt| - if let Ok(formatted) = dt.format(&Rfc3339) { - formatted.to_string() - } else { - dt.to_string() - }).collect::>().join(","))).into(), + body: Bytes::from(format!( + r#"["{}"]"#, + body.iter() + .map(|dt| if let Ok(formatted) = dt.format(&Rfc3339) { + formatted.to_string() + } else { + dt.to_string() + }) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -354,7 +367,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!(r#"[{}]"#, body.iter().map(|s| format!(r#""{}""#, s)).collect::>().join(","))).into(), + body: Bytes::from(format!( + r#"[{}]"#, + body.iter() + .map(|s| format!(r#""{}""#, s)) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -364,7 +384,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec<&str>) -> Result { Ok(Self { - body: Bytes::from(format!(r#"[{}]"#, body.iter().map(|s| format!(r#""{}""#, s)).collect::>().join(","))).into(), + body: Bytes::from(format!( + r#"[{}]"#, + body.iter() + .map(|s| format!(r#""{}""#, s)) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -374,7 +401,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!("[{}]", body.iter().map(|f| f.to_string()).collect::>().join(","))).into(), + body: Bytes::from(format!( + "[{}]", + body.iter() + .map(|f| f.to_string()) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -384,7 +418,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!("[{}]", body.iter().map(|f| f.to_string()).collect::>().join(","))).into(), + body: Bytes::from(format!( + "[{}]", + body.iter() + .map(|f| f.to_string()) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -394,7 +435,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!("[{}]", body.iter().map(|i| i.to_string()).collect::>().join(","))).into(), + body: Bytes::from(format!( + "[{}]", + body.iter() + .map(|i| i.to_string()) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } @@ -404,7 +452,14 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!("[{}]", body.iter().map(|i| i.to_string()).collect::>().join(","))).into(), + body: Bytes::from(format!( + "[{}]", + body.iter() + .map(|i| i.to_string()) + .collect::>() + .join(",") + )) + .into(), phantom: PhantomData, }) } From edb729f98396ac5618a6b946b7bf7be61de3345f Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Mon, 14 Jul 2025 14:53:23 -0700 Subject: [PATCH 3/7] Remove unnecessary to_string() --- sdk/typespec/typespec_client_core/src/http/request/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/typespec/typespec_client_core/src/http/request/mod.rs b/sdk/typespec/typespec_client_core/src/http/request/mod.rs index 9e49a4fa09..9999c0e67e 100644 --- a/sdk/typespec/typespec_client_core/src/http/request/mod.rs +++ b/sdk/typespec/typespec_client_core/src/http/request/mod.rs @@ -499,7 +499,7 @@ impl TryFrom> for RequestContent { if let Ok(formatted) = v.format(&Rfc3339) { format!(r#""{}":"{}""#, k, formatted) } else { - format!(r#""{}":"{}""#, k, v.to_string()) + format!(r#""{}":"{}""#, k, v) } }) .collect::>() From 3a4ac71f4c9c639b3a1f580559f8f33da8a9b2d6 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Mon, 14 Jul 2025 17:40:39 -0700 Subject: [PATCH 4/7] Dependency --- sdk/typespec/typespec_client_core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/typespec/typespec_client_core/Cargo.toml b/sdk/typespec/typespec_client_core/Cargo.toml index e687805b32..e2ef1ddb41 100644 --- a/sdk/typespec/typespec_client_core/Cargo.toml +++ b/sdk/typespec/typespec_client_core/Cargo.toml @@ -20,7 +20,7 @@ pin-project.workspace = true quick-xml = { workspace = true, optional = true } rand.workspace = true reqwest = { workspace = true, optional = true } -rust_decimal = "1.37.2" +rust_decimal = { workspace = true, optional = true } serde.workspace = true serde_json.workspace = true time.workspace = true From 0b842c2c406a7c899a9e393f6f9ad46bebd1efbb Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Mon, 14 Jul 2025 19:01:45 -0700 Subject: [PATCH 5/7] Optional dependency --- Cargo.toml | 1 + sdk/typespec/typespec_client_core/Cargo.toml | 1 + sdk/typespec/typespec_client_core/src/http/request/mod.rs | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f7f7f592e8..42e4418f09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,6 +97,7 @@ reqwest = { version = "0.12.22", features = [ "json", "stream", ], default-features = false } +rust_decimal = "1.37.2" rustc_version = "0.4" serde = { version = "1.0", features = ["derive"] } serde_amqp = { version = "0.14", features = ["uuid"] } diff --git a/sdk/typespec/typespec_client_core/Cargo.toml b/sdk/typespec/typespec_client_core/Cargo.toml index e2ef1ddb41..72fad63e49 100644 --- a/sdk/typespec/typespec_client_core/Cargo.toml +++ b/sdk/typespec/typespec_client_core/Cargo.toml @@ -59,6 +59,7 @@ reqwest_rustls = [ test = [] # Enables extra tracing including error bodies that may contain PII. tokio = ["tokio/fs", "tokio/sync", "tokio/time", "tokio/io-util"] xml = ["dep:quick-xml"] +rust_decimal = ["dep:rust_decimal"] [[example]] name = "core_binary_data_request" diff --git a/sdk/typespec/typespec_client_core/src/http/request/mod.rs b/sdk/typespec/typespec_client_core/src/http/request/mod.rs index 9999c0e67e..f69016be6a 100644 --- a/sdk/typespec/typespec_client_core/src/http/request/mod.rs +++ b/sdk/typespec/typespec_client_core/src/http/request/mod.rs @@ -16,12 +16,14 @@ use crate::{ time::OffsetDateTime, }; use bytes::Bytes; -use rust_decimal::Decimal; use serde::Serialize; use serde_json::Value; use std::{collections::HashMap, fmt, marker::PhantomData, str::FromStr}; use time::format_description::well_known::Rfc3339; +#[cfg(feature = "rust_decimal")] +use rust_decimal::Decimal; + /// An HTTP Body. #[derive(Clone)] pub enum Body { @@ -315,6 +317,7 @@ impl TryFrom for RequestContent { } } +#[cfg(feature = "rust_decimal")] impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Option) -> Result { From 7de78b19704790cbeb8495f53f6dfe9a8bf38a74 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Mon, 14 Jul 2025 21:23:53 -0700 Subject: [PATCH 6/7] Use serde_json --- .../src/http/request/mod.rs | 144 ++++-------------- 1 file changed, 26 insertions(+), 118 deletions(-) diff --git a/sdk/typespec/typespec_client_core/src/http/request/mod.rs b/sdk/typespec/typespec_client_core/src/http/request/mod.rs index f69016be6a..f965b52d06 100644 --- a/sdk/typespec/typespec_client_core/src/http/request/mod.rs +++ b/sdk/typespec/typespec_client_core/src/http/request/mod.rs @@ -332,14 +332,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - "[{}]", - body.iter() - .map(|b| b.to_string()) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -349,17 +342,12 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - r#"["{}"]"#, - body.iter() - .map(|dt| if let Ok(formatted) = dt.format(&Rfc3339) { - formatted.to_string() - } else { - dt.to_string() - }) - .collect::>() - .join(",") - )) + body: Bytes::from(serde_json::to_string( + &body + .iter() + .map(|v| v.format(&Rfc3339).unwrap_or_else(|_| v.to_string())) + .collect::>(), + )?) .into(), phantom: PhantomData, }) @@ -370,14 +358,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - r#"[{}]"#, - body.iter() - .map(|s| format!(r#""{}""#, s)) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -387,14 +368,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec<&str>) -> Result { Ok(Self { - body: Bytes::from(format!( - r#"[{}]"#, - body.iter() - .map(|s| format!(r#""{}""#, s)) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -404,14 +378,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - "[{}]", - body.iter() - .map(|f| f.to_string()) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -421,14 +388,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - "[{}]", - body.iter() - .map(|f| f.to_string()) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -438,14 +398,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - "[{}]", - body.iter() - .map(|i| i.to_string()) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -455,14 +408,7 @@ impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: Vec) -> Result { Ok(Self { - body: Bytes::from(format!( - "[{}]", - body.iter() - .map(|i| i.to_string()) - .collect::>() - .join(",") - )) - .into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -481,13 +427,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":{}"#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -496,19 +437,16 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body + let body_rfc3339: HashMap = body .into_iter() .map(|(k, v)| { - if let Ok(formatted) = v.format(&Rfc3339) { - format!(r#""{}":"{}""#, k, formatted) - } else { - format!(r#""{}":"{}""#, k, v) - } + let formatted = v.format(&Rfc3339).unwrap_or_else(|_| v.to_string()); + (k, formatted) }) - .collect::>() - .join(","); + .collect(); + Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body_rfc3339)?).into(), phantom: PhantomData, }) } @@ -517,13 +455,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":"{}""#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -532,13 +465,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":{}"#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -547,13 +475,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":{}"#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -562,13 +485,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":{}"#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -577,13 +495,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":{}"#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } @@ -592,13 +505,8 @@ impl TryFrom> for RequestContent { impl TryFrom> for RequestContent { type Error = crate::Error; fn try_from(body: HashMap) -> Result { - let body_str = body - .into_iter() - .map(|(k, v)| format!(r#""{}":{}"#, k, v)) - .collect::>() - .join(","); Ok(Self { - body: Bytes::from(format!(r#"{{{}}}"#, body_str)).into(), + body: Bytes::from(serde_json::to_string(&body)?).into(), phantom: PhantomData, }) } From 7dd32988a00c3f6d825313f97d9780b8865c5e23 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk Date: Fri, 18 Jul 2025 13:26:42 -0700 Subject: [PATCH 7/7] PR Feedback --- sdk/typespec/typespec_client_core/Cargo.toml | 2 +- .../src/http/request/mod.rs | 332 +++++++++--------- 2 files changed, 169 insertions(+), 165 deletions(-) diff --git a/sdk/typespec/typespec_client_core/Cargo.toml b/sdk/typespec/typespec_client_core/Cargo.toml index 72fad63e49..7402664041 100644 --- a/sdk/typespec/typespec_client_core/Cargo.toml +++ b/sdk/typespec/typespec_client_core/Cargo.toml @@ -59,7 +59,7 @@ reqwest_rustls = [ test = [] # Enables extra tracing including error bodies that may contain PII. tokio = ["tokio/fs", "tokio/sync", "tokio/time", "tokio/io-util"] xml = ["dep:quick-xml"] -rust_decimal = ["dep:rust_decimal"] +decimal = ["dep:rust_decimal"] [[example]] name = "core_binary_data_request" diff --git a/sdk/typespec/typespec_client_core/src/http/request/mod.rs b/sdk/typespec/typespec_client_core/src/http/request/mod.rs index f965b52d06..d15cc7431a 100644 --- a/sdk/typespec/typespec_client_core/src/http/request/mod.rs +++ b/sdk/typespec/typespec_client_core/src/http/request/mod.rs @@ -18,10 +18,10 @@ use crate::{ use bytes::Bytes; use serde::Serialize; use serde_json::Value; -use std::{collections::HashMap, fmt, marker::PhantomData, str::FromStr}; +use std::{collections::HashMap, convert::Infallible, fmt, marker::PhantomData, str::FromStr}; use time::format_description::well_known::Rfc3339; -#[cfg(feature = "rust_decimal")] +#[cfg(feature = "decimal")] use rust_decimal::Decimal; /// An HTTP Body. @@ -297,19 +297,9 @@ impl TryFrom<&'static str> for RequestContent { } } -impl TryFrom for RequestContent { - type Error = crate::Error; - fn try_from(body: Value) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) - } -} - impl TryFrom for RequestContent { - type Error = crate::Error; - fn try_from(body: bool) -> Result { + type Error = Infallible; + fn try_from(body: bool) -> Result { Ok(Self { body: Bytes::from(body.to_string()).into(), phantom: PhantomData, @@ -317,10 +307,10 @@ impl TryFrom for RequestContent { } } -#[cfg(feature = "rust_decimal")] +#[cfg(feature = "decimal")] impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Option) -> Result { + type Error = Infallible; + fn try_from(body: Option) -> Result { Ok(Self { body: Bytes::from(body.map(|d| d.to_string()).unwrap_or_default()).into(), phantom: PhantomData, @@ -328,187 +318,201 @@ impl TryFrom> for RequestContent { } } -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) +pub mod json { + use super::*; + + impl TryFrom for RequestContent { + type Error = crate::Error; + fn try_from(body: Value) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string( - &body - .iter() - .map(|v| v.format(&Rfc3339).unwrap_or_else(|_| v.to_string())) - .collect::>(), - )?) - .into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string( + &body + .iter() + .map(|v| v.format(&Rfc3339).unwrap_or_else(|_| v.to_string())) + .collect::>(), + )?) + .into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec<&str>) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec<&str>) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: Vec) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: Vec) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - let body_rfc3339: HashMap = body - .into_iter() - .map(|(k, v)| { - let formatted = v.format(&Rfc3339).unwrap_or_else(|_| v.to_string()); - (k, formatted) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, }) - .collect(); + } + } - Ok(Self { - body: Bytes::from(serde_json::to_string(&body_rfc3339)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + let body_rfc3339: HashMap = body + .into_iter() + .map(|(k, v)| { + let formatted = v.format(&Rfc3339).unwrap_or_else(|_| v.to_string()); + (k, formatted) + }) + .collect(); + + Ok(Self { + body: Bytes::from(serde_json::to_string(&body_rfc3339)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } -} -impl TryFrom> for RequestContent { - type Error = crate::Error; - fn try_from(body: HashMap) -> Result { - Ok(Self { - body: Bytes::from(serde_json::to_string(&body)?).into(), - phantom: PhantomData, - }) + impl TryFrom> for RequestContent { + type Error = crate::Error; + fn try_from(body: HashMap) -> Result { + Ok(Self { + body: Bytes::from(serde_json::to_string(&body)?).into(), + phantom: PhantomData, + }) + } } }