From 6add9312ae392301388bbe13acdaf5b2dfa22c48 Mon Sep 17 00:00:00 2001 From: Carter Green Date: Wed, 15 Apr 2026 15:36:54 +0000 Subject: [PATCH 1/2] MOD: Change to bon for builder generation --- CHANGELOG.md | 18 ++++++++++++++ Cargo.toml | 2 +- examples/live_smoke_test.rs | 2 +- src/historical/batch.rs | 47 +++++++++++++++++++----------------- src/historical/metadata.rs | 18 ++++++-------- src/historical/symbology.rs | 9 +++---- src/historical/timeseries.rs | 23 +++++++----------- src/live.rs | 12 ++++----- src/live/client.rs | 4 +-- src/reference/adjustment.rs | 13 +++++----- src/reference/corporate.rs | 17 ++++++------- src/reference/security.rs | 21 ++++++++-------- 12 files changed, 97 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30d7d50..108cc12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.47.0 - TBD + +### Enhancements +- Replaced `typed-builder` dependency with `bon` for all parameter builder structs +- Added `maybe_` prefixed setters for all `Option` fields on parameter builders, allowing + callers to pass `Option` directly (e.g. `maybe_start(Some(datetime))` or `maybe_start(None)`) + +### Breaking changes +- Changed `use_snapshot()` setter on `Subscription` builder to require an explicit `bool` + argument: `.use_snapshot()` becomes `.use_snapshot(true)` +- Changed `map_symbols` field in `SubmitJobParams` from `bool` to `Option` +- Changed `limit()` setter on `GetRangeParams`, `GetRangeToFileParams`, `GetQueryParams`, and + `SubmitJobParams` builders to accept `NonZeroU64` instead of `Option`. + Use `maybe_limit()` for the previous behavior of passing an `Option` directly + +### Bug fixes +- Removed `#[doc(hidden)]` from `Subscription::use_snapshot` + ## 0.46.0 - 2026-04-07 ### Enhancements diff --git a/Cargo.toml b/Cargo.toml index 58891f6..04833ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ tokio = { version = ">=1.41", features = ["io-util", "macros"] } # Stream utils tokio-util = { version = "0.7", features = ["io"], optional = true } tracing = "0.1" -typed-builder = "0.23" +bon = "3" zstd = { version = "0.13", optional = true } [dev-dependencies] diff --git a/examples/live_smoke_test.rs b/examples/live_smoke_test.rs index 07db40d..b5b8f7b 100644 --- a/examples/live_smoke_test.rs +++ b/examples/live_smoke_test.rs @@ -124,7 +124,7 @@ async fn run_with_snapshot(args: Args, mut client: LiveClient) -> anyhow::Result .schema(args.schema) .symbols(args.symbols) .stype_in(args.stype) - .use_snapshot() + .use_snapshot(true) .build(), ) .await?; diff --git a/src/historical/batch.rs b/src/historical/batch.rs index 5316409..7a540ad 100644 --- a/src/historical/batch.rs +++ b/src/historical/batch.rs @@ -21,7 +21,6 @@ use tokio::{ io::{AsyncReadExt, BufWriter}, }; use tracing::{debug, error, info, info_span, instrument, warn, Instrument}; -use typed_builder::TypedBuilder; use crate::{ deserialize::{deserialize_date_time, deserialize_opt_date_time}, @@ -73,7 +72,13 @@ impl BatchClient<'_> { ("compression", params.compression.to_string()), ("pretty_px", params.pretty_px.to_string()), ("pretty_ts", params.pretty_ts.to_string()), - ("map_symbols", params.map_symbols.to_string()), + ( + "map_symbols", + params + .map_symbols + .unwrap_or(params.encoding != Encoding::Dbn) + .to_string(), + ), ("split_symbols", params.split_symbols.to_string()), ("delivery", params.delivery.to_string()), ("stype_in", params.stype_in.to_string()), @@ -375,20 +380,20 @@ pub enum JobState { /// The parameters for [`BatchClient::submit_job()`]. Use [`SubmitJobParams::builder()`] to /// get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct SubmitJobParams { /// The dataset code. - #[builder(setter(transform = |dt: impl ToString| dt.to_string()))] + #[builder(with = |d: impl ToString| d.to_string())] pub dataset: String, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The data record schema. pub schema: Schema, /// The request range with an inclusive start and an exclusive end. /// /// Filters on `ts_recv` if it exists in the schema, otherwise `ts_event`. - #[builder(setter(into))] + #[builder(into)] pub date_time_range: DateTimeRange, /// The data encoding. Defaults to [`Dbn`](Encoding::Dbn). #[builder(default = Encoding::Dbn)] @@ -405,10 +410,9 @@ pub struct SubmitJobParams { #[builder(default)] pub pretty_ts: bool, /// If `true`, a symbol field will be included with each text-encoded - /// record. If `None`, will default to `true` for [`Encoding::Csv`] and [`Encoding::Json`] encodings, - /// and `false` for [`Encoding::Dbn`]. - #[builder(default_code = "*encoding != Encoding::Dbn")] - pub map_symbols: bool, + /// record. Defaults to `true` for [`Encoding::Csv`] and [`Encoding::Json`] encodings + /// when `None`, and `false` for [`Encoding::Dbn`]. + pub map_symbols: Option, /// If `true`, files will be split by raw symbol. Cannot be requested with [`Symbols::All`]. #[builder(default)] pub split_symbols: bool, @@ -421,7 +425,6 @@ pub struct SubmitJobParams { pub split_duration: SplitDuration, /// The optional maximum size (in bytes) of each batched data file before being split. /// Must be an integer between 1e9 and 10e9 inclusive (1GB - 10GB). Defaults to `None`. - #[builder(default, setter(strip_option))] pub split_size: Option, /// The delivery mechanism for the batched data files once processed. /// Only [`Download`](Delivery::Download) is supported at this time. @@ -439,7 +442,6 @@ pub struct SubmitJobParams { #[builder(default = SType::InstrumentId)] pub stype_out: SType, /// The optional maximum number of records to return. Defaults to no limit. - #[builder(default)] pub limit: Option, } @@ -523,14 +525,12 @@ pub struct BatchJob { /// The parameters for [`BatchClient::list_jobs()`]. Use [`ListJobsParams::builder()`] to /// get a builder type with all the preset defaults. -#[derive(Debug, Clone, Default, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, Default, bon::Builder, PartialEq, Eq)] pub struct ListJobsParams { /// The optional filter for job states. If `None`, defaults to all except `Expired`. - #[builder(default, setter(strip_option))] pub states: Option>, /// The optional filter for timestamp submitted (will not include jobs prior to /// this time). - #[builder(default, setter(strip_option))] pub since: Option, } @@ -549,16 +549,16 @@ pub struct BatchFileDesc { /// The parameters for [`BatchClient::download()`]. Use [`DownloadParams::builder()`] to /// get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct DownloadParams { /// The directory to download the file(s) to. - #[builder(setter(transform = |dt: impl Into| dt.into()))] + #[builder(into)] pub output_dir: PathBuf, /// The batch job identifier. - #[builder(setter(transform = |dt: impl ToString| dt.to_string()))] + #[builder(with = |id: impl ToString| id.to_string())] pub job_id: String, /// `None` means all files associated with the job will be downloaded. - #[builder(default, setter(transform = |filename: impl ToString| Some(filename.to_string())))] + #[builder(with = |f: impl ToString| f.to_string())] pub filename_to_download: Option, } @@ -803,6 +803,8 @@ mod tests { const START: time::OffsetDateTime = datetime!(2023 - 06 - 14 00:00 UTC); const END: time::OffsetDateTime = datetime!(2023 - 06 - 17 00:00 UTC); + // When not explicitly set, map_symbols is None (resolved at request time + // based on encoding) let params = SubmitJobParams::builder() .dataset(Dataset::GlbxMdp3) .encoding(Encoding::Dbn) @@ -811,7 +813,7 @@ mod tests { .date_time_range(START..END) .build(); assert_eq!(params.encoding, Encoding::Dbn); - assert_eq!(params.map_symbols, false); + assert!(params.map_symbols.is_none()); let params = SubmitJobParams::builder() .dataset(Dataset::GlbxMdp3) @@ -821,8 +823,9 @@ mod tests { .date_time_range(START..END) .build(); assert_eq!(params.encoding, Encoding::Csv); - assert_eq!(params.map_symbols, true); + assert!(params.map_symbols.is_none()); + // When explicitly set, map_symbols preserves the value let params = SubmitJobParams::builder() .dataset(Dataset::GlbxMdp3) .encoding(Encoding::Json) @@ -832,7 +835,7 @@ mod tests { .map_symbols(false) .build(); assert_eq!(params.encoding, Encoding::Json); - assert_eq!(params.map_symbols, false); + assert_eq!(params.map_symbols, Some(false)); Ok(()) } diff --git a/src/historical/metadata.rs b/src/historical/metadata.rs index 5e45779..8ed1f7a 100644 --- a/src/historical/metadata.rs +++ b/src/historical/metadata.rs @@ -6,7 +6,6 @@ use dbn::{Encoding, SType, Schema}; use reqwest::RequestBuilder; use serde::{Deserialize, Deserializer}; use tracing::instrument; -use typed_builder::TypedBuilder; use crate::{ deserialize::deserialize_date_time, @@ -233,7 +232,7 @@ pub struct PublisherDetail { /// The parameters for [`MetadataClient::list_fields()`]. Use /// [`ListFieldsParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct ListFieldsParams { /// The encoding to request fields for. pub encoding: Encoding, @@ -263,14 +262,14 @@ pub struct UnitPricesForMode { /// The parameters for [`MetadataClient::get_dataset_condition()`]. Use /// [`GetDatasetConditionParams::builder()`] to get a builder type with all the preset /// defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetDatasetConditionParams { /// The dataset code. - #[builder(setter(transform = |dataset: impl ToString| dataset.to_string()))] + #[builder(with = |d: impl ToString| d.to_string())] pub dataset: String, /// The UTC date request range with an inclusive start date and an inclusive end date. /// If `None` then will return all available dates. - #[builder(default, setter(transform = |dr: impl Into| Some(dr.into())))] + #[builder(into)] pub date_range: Option, } @@ -310,25 +309,24 @@ impl From for DateTimeRange { } /// The parameters for several metadata requests. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetQueryParams { /// The dataset code. - #[builder(setter(transform = |dataset: impl ToString| dataset.to_string()))] + #[builder(with = |d: impl ToString| d.to_string())] pub dataset: String, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The data record schema. pub schema: Schema, /// The request range with an inclusive start and an exclusive end. - #[builder(setter(into))] + #[builder(into)] pub date_time_range: DateTimeRange, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](dbn::enums::SType::RawSymbol). #[builder(default = SType::RawSymbol)] pub stype_in: SType, /// The optional maximum number of records to return. Defaults to no limit. - #[builder(default)] pub limit: Option, } diff --git a/src/historical/symbology.rs b/src/historical/symbology.rs index 41424eb..669c368 100644 --- a/src/historical/symbology.rs +++ b/src/historical/symbology.rs @@ -6,7 +6,6 @@ use dbn::{MappingInterval, Metadata, SType, TsSymbolMap}; use reqwest::RequestBuilder; use serde::Deserialize; use tracing::instrument; -use typed_builder::TypedBuilder; use crate::{historical::AddToForm, Symbols}; @@ -57,13 +56,13 @@ impl SymbologyClient<'_> { /// The parameters for [`SymbologyClient::resolve()`]. Use [`ResolveParams::builder()`] /// to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct ResolveParams { /// The dataset code. - #[builder(setter(transform = |dt: impl ToString| dt.to_string()))] + #[builder(with = |d: impl ToString| d.to_string())] pub dataset: String, /// The symbols to resolve. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](dbn::enums::SType::RawSymbol). @@ -77,7 +76,7 @@ pub struct ResolveParams { #[builder(default = SType::InstrumentId)] pub stype_out: SType, /// The UTC date range with an inclusive start and an exclusive end. - #[builder(setter(into))] + #[builder(into)] pub date_range: DateRange, } diff --git a/src/historical/timeseries.rs b/src/historical/timeseries.rs index a20de8e..de031eb 100644 --- a/src/historical/timeseries.rs +++ b/src/historical/timeseries.rs @@ -16,7 +16,6 @@ use tokio::{ }; use tokio_util::{bytes::Bytes, io::StreamReader}; use tracing::{error, instrument}; -use typed_builder::TypedBuilder; use crate::{ historical::{check_warnings, AddToForm, Limit}, @@ -163,19 +162,19 @@ impl TimeseriesClient<'_> { /// The parameters for [`TimeseriesClient::get_range()`]. Use /// [`GetRangeParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetRangeParams { /// The dataset code. - #[builder(setter(transform = |dt: impl ToString| dt.to_string()))] + #[builder(with = |d: impl ToString| d.to_string())] pub dataset: String, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The data record schema. pub schema: Schema, /// The request range with an inclusive start and an exclusive end. /// Filters on `ts_recv` if it exists in the schema, otherwise `ts_event`. - #[builder(setter(into))] + #[builder(into)] pub date_time_range: DateTimeRange, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](dbn::enums::SType::RawSymbol). @@ -189,11 +188,9 @@ pub struct GetRangeParams { #[builder(default = SType::InstrumentId)] pub stype_out: SType, /// The optional maximum number of records to return. Defaults to no limit. - #[builder(default)] pub limit: Option, /// How to decode DBN from prior versions. Defaults to upgrade to the latest /// version. - #[builder(default, setter(strip_option))] #[deprecated( since = "0.28.0", note = "Use the upgrade_policy configuration option on HistoricalClient" @@ -203,19 +200,19 @@ pub struct GetRangeParams { /// The parameters for [`TimeseriesClient::get_range_to_file()`]. Use /// [`GetRangeToFileParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetRangeToFileParams { /// The dataset code. - #[builder(setter(transform = |dt: impl ToString| dt.to_string()))] + #[builder(with = |d: impl ToString| d.to_string())] pub dataset: String, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The data record schema. pub schema: Schema, /// The request range with an inclusive start and an exclusive end. /// Filters on `ts_recv` if it exists in the schema, otherwise `ts_event`. - #[builder(setter(into))] + #[builder(into)] pub date_time_range: DateTimeRange, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](dbn::enums::SType::RawSymbol). @@ -229,18 +226,16 @@ pub struct GetRangeToFileParams { #[builder(default = SType::InstrumentId)] pub stype_out: SType, /// The optional maximum number of records to return. Defaults to no limit. - #[builder(default)] pub limit: Option, /// How to decode DBN from prior versions. Defaults to upgrade to the latest /// version. - #[builder(default, setter(strip_option))] #[deprecated( since = "0.28.0", note = "Use the upgrade_policy configuration option on HistoricalClient" )] pub upgrade_policy: Option, /// The file path to persist the stream data to. - #[builder(default, setter(transform = |p: impl Into| p.into()))] + #[builder(default, into)] pub path: PathBuf, } diff --git a/src/live.rs b/src/live.rs index 4cf0da0..8f2e0c8 100644 --- a/src/live.rs +++ b/src/live.rs @@ -9,7 +9,6 @@ use dbn::{Compression, SType, Schema, VersionUpgradePolicy}; use time::{Duration, OffsetDateTime}; use tokio::net::{lookup_host, ToSocketAddrs}; use tracing::warn; -use typed_builder::TypedBuilder; use crate::{ApiKey, DateTimeLike, Symbols}; @@ -44,10 +43,11 @@ pub enum SlowReaderBehavior { } /// A subscription for real-time or intraday historical data. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] +#[builder(derive(Clone))] pub struct Subscription { /// The symbols of the instruments to subscribe to. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The data record schema of data to subscribe to. pub schema: Schema, @@ -60,15 +60,13 @@ pub struct Subscription { /// /// Cannot be specified after the session is started with [`LiveClient::start`](crate::LiveClient::start). /// See [`Intraday Replay`](https://databento.com/docs/api-reference-live/basics/intraday-replay). - #[builder(default, setter(transform = |dt: impl DateTimeLike| Some(dt.to_date_time())))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub start: Option, - #[doc(hidden)] /// Request subscription with snapshot. Only supported with `Mbo` schema. /// Defaults to `false`. Conflicts with the `start` parameter. - #[builder(setter(strip_bool))] + #[builder(default)] pub use_snapshot: bool, /// The optional numerical identifier associated with this subscription. - #[builder(default, setter(strip_option))] pub id: Option, } diff --git a/src/live/client.rs b/src/live/client.rs index f920564..3d853e0 100644 --- a/src/live/client.rs +++ b/src/live/client.rs @@ -922,7 +922,7 @@ mod tests { .symbols(vec!["MSFT", "TSLA", "QQQ"]) .schema(Schema::Ohlcv1M) .stype_in(SType::RawSymbol) - .use_snapshot() + .use_snapshot(true) .build(); fixture.expect_subscribe(subscription.clone(), true); client.subscribe(subscription).await.unwrap(); @@ -941,7 +941,7 @@ mod tests { .schema(Schema::Ohlcv1M) .stype_in(SType::RawSymbol) .start(time::OffsetDateTime::now_utc()) - .use_snapshot() + .use_snapshot(true) .build(), ) .await diff --git a/src/reference/adjustment.rs b/src/reference/adjustment.rs index 6a6a426..3e17cb5 100644 --- a/src/reference/adjustment.rs +++ b/src/reference/adjustment.rs @@ -4,7 +4,6 @@ use dbn::{Compression, SType}; use serde::Deserialize; use time::{Date, OffsetDateTime}; use tracing::instrument; -use typed_builder::TypedBuilder; use crate::{ deserialize::deserialize_date_time, @@ -55,18 +54,18 @@ impl AdjustmentFactorsClient<'_> { /// The parameters for [`AdjustmentFactorsClient::get_range()`]. Use /// [`GetRangeParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetRangeParams { /// The inclusive start time of the request range. Filters on `index`. - #[builder(setter(transform = |dt: impl DateTimeLike| dt.to_date_time()))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub start: OffsetDateTime, /// The exclusive end time of the request range. Filters on `index`. /// /// If `None`, all data after `start` will be included in the response. - #[builder(default, setter(transform = |dt: impl DateTimeLike| Some(dt.to_date_time())))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub end: Option, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](SType::RawSymbol). @@ -74,11 +73,11 @@ pub struct GetRangeParams { pub stype_in: SType, /// An optional list of country codes to filter for. By default all countries are /// included. - #[builder(default, setter(into))] + #[builder(default, into)] pub countries: Vec, /// An optional list of security types to filter for. By default all security types /// are included. - #[builder(default, setter(into))] + #[builder(default, into)] pub security_types: Vec, } diff --git a/src/reference/corporate.rs b/src/reference/corporate.rs index 7995f26..6458fa9 100644 --- a/src/reference/corporate.rs +++ b/src/reference/corporate.rs @@ -6,7 +6,6 @@ use dbn::{Compression, SType}; use serde::Deserialize; use time::{Date, OffsetDateTime}; use tracing::instrument; -use typed_builder::TypedBuilder; use crate::{ deserialize::{deserialize_date_time, deserialize_opt_date_time_hash_map}, @@ -89,40 +88,40 @@ pub enum Index { /// The parameters for [`CorporateActionsClient::get_range()`]. Use /// [`GetRangeParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetRangeParams { /// The inclusive start time of the request range. Filters on `index`. - #[builder(setter(transform = |dt: impl DateTimeLike| dt.to_date_time()))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub start: OffsetDateTime, /// The exclusive end time of the request range. Filters on `index`. /// /// If `None`, all data after `start` will be included in the response. - #[builder(default, setter(transform = |dt: impl DateTimeLike| Some(dt.to_date_time())))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub end: Option, /// The timestamp to use for filtering. #[builder(default)] pub index: Index, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](SType::RawSymbol). #[builder(default = SType::RawSymbol)] pub stype_in: SType, /// An optional list of event types to filter for. By default all events are included. - #[builder(default, setter(into))] + #[builder(default, into)] pub events: Vec, /// An optional list of country codes to filter for. By default all countries are /// included. - #[builder(default, setter(into))] + #[builder(default, into)] pub countries: Vec, /// An optional list of listing exchanges to filter for. By default all exchanges are /// included. - #[builder(default, setter(into))] + #[builder(default, into)] pub exchanges: Vec, /// An optional list of security types to filter for. By default all security types /// are included. - #[builder(default, setter(into))] + #[builder(default, into)] pub security_types: Vec, } diff --git a/src/reference/security.rs b/src/reference/security.rs index 39df37c..d9a7bc0 100644 --- a/src/reference/security.rs +++ b/src/reference/security.rs @@ -7,7 +7,6 @@ use reqwest::RequestBuilder; use serde::Deserialize; use time::{Date, OffsetDateTime}; use tracing::instrument; -use typed_builder::TypedBuilder; use crate::{ deserialize::deserialize_date_time, @@ -94,21 +93,21 @@ pub enum Index { /// The parameters for [`SecurityMasterClient::get_range()`]. Use /// [`GetRangeParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetRangeParams { /// The inclusive start time of the request range. Filters on `index`. - #[builder(setter(transform = |dt: impl DateTimeLike| dt.to_date_time()))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub start: OffsetDateTime, /// The exclusive end time of the request range. Filters on `index`. /// /// If `None`, all data after `start` will be included in the response. - #[builder(default, setter(transform = |dt: impl DateTimeLike| Some(dt.to_date_time())))] + #[builder(with = |dt: impl DateTimeLike| dt.to_date_time())] pub end: Option, /// The timestamp to use for filtering. #[builder(default)] pub index: Index, /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](SType::RawSymbol). @@ -116,20 +115,20 @@ pub struct GetRangeParams { pub stype_in: SType, /// An optional list of country codes to filter for. By default all countries are /// included. - #[builder(default, setter(into))] + #[builder(default, into)] pub countries: Vec, /// An optional list of security types to filter for. By default all security types /// are included. - #[builder(default, setter(into))] + #[builder(default, into)] pub security_types: Vec, } /// The parameters for [`SecurityMasterClient::get_last()`]. Use /// [`GetLastParams::builder()`] to get a builder type with all the preset defaults. -#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq)] +#[derive(Debug, Clone, bon::Builder, PartialEq, Eq)] pub struct GetLastParams { /// The symbols to filter for. - #[builder(setter(into))] + #[builder(into)] pub symbols: Symbols, /// The symbology type of the input `symbols`. Defaults to /// [`RawSymbol`](SType::RawSymbol). @@ -137,11 +136,11 @@ pub struct GetLastParams { pub stype_in: SType, /// An optional list of country codes to filter for. By default all countries are /// included. - #[builder(default, setter(into))] + #[builder(default, into)] pub countries: Vec, /// An optional list of security types to filter for. By default all security types /// are included. - #[builder(default, setter(into))] + #[builder(default, into)] pub security_types: Vec, } From abb462df71acdbf94a18cc7cf19ab20c2f29997b Mon Sep 17 00:00:00 2001 From: Carter Green Date: Tue, 14 Apr 2026 14:34:09 -0500 Subject: [PATCH 2/2] VER: Release Rust 0.47.0 --- CHANGELOG.md | 13 ++++++++++++- Cargo.toml | 4 ++-- src/live/client.rs | 15 ++++++--------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 108cc12..6977040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,22 @@ # Changelog -## 0.47.0 - TBD +## 0.47.0 - 2026-04-15 ### Enhancements - Replaced `typed-builder` dependency with `bon` for all parameter builder structs - Added `maybe_` prefixed setters for all `Option` fields on parameter builders, allowing callers to pass `Option` directly (e.g. `maybe_start(Some(datetime))` or `maybe_start(None)`) +- Upgraded DBN version to 0.54.0: + - Added `RecordBuf`, an owned stack-allocated buffer for holding a DBN record of + dynamic type. Complements `RecordRef` (borrowed, dynamic) and concrete types + (owned, static). Supports `get()`, `try_get()`, `set()`, `upgrade()`, and + cross-capacity `PartialEq` + - Added `RecordRefMut` for mutable non-owning references to DBN records + - Added `RecordRef::to_owned()` and `RecordRefMut::to_owned()` for converting + borrowed records to an owned `RecordBuf` + - Added `Hash`, `PartialEq`, and `Eq` for `RecordRef`, including cross-type equality + between `RecordBuf` and `RecordRef` + - Changed `RecordHeader` to be `Copy` ### Breaking changes - Changed `use_snapshot()` setter on `Subscription` builder to require an explicit `bool` diff --git a/Cargo.toml b/Cargo.toml index 04833ed..e361816 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "databento" authors = ["Databento "] -version = "0.46.0" +version = "0.47.0" edition = "2021" repository = "https://github.com/databento/databento-rs" description = "Official Databento client library" @@ -33,7 +33,7 @@ live = ["tokio/net", "tokio/time"] chrono = ["dep:chrono"] [dependencies] -dbn = { version = "0.53", features = ["async", "serde"] } +dbn = { version = "0.54", features = ["async", "serde"] } async-compression = { version = "0.4", features = ["tokio", "zstd"], optional = true } chrono = { version = ">=0.4.34", optional = true, default-features = false, features = ["alloc"] } diff --git a/src/live/client.rs b/src/live/client.rs index 3d853e0..06d5bf6 100644 --- a/src/live/client.rs +++ b/src/live/client.rs @@ -588,7 +588,7 @@ mod tests { enums::rtype, publishers::Dataset, record::{HasRType, OhlcvMsg, RecordHeader, TradeMsg, WithTsOut}, - FlagSet, Mbp10Msg, MetadataBuilder, Record, SType, Schema, + FlagSet, Mbp10Msg, MetadataBuilder, Record, RecordBuf, SType, Schema, }; use time::{Duration, OffsetDateTime}; use tokio::{ @@ -704,8 +704,8 @@ mod tests { info!("Sent: {}", &bytes[..bytes.len() - 1]) } - async fn send_record(&mut self, record: Box + Send>) { - let bytes = (*record).as_ref(); + async fn send_record(&mut self, record: RecordBuf) { + let bytes = record.as_ref(); // test for partial read bugs let half = bytes.len() / 2; self.stream().write_all(&bytes[..half]).await.unwrap(); @@ -777,7 +777,7 @@ mod tests { Send(String), Subscribe(Subscription, bool), Start, - SendRecord(Box + Send>), + SendRecord(RecordBuf), Disconnect, } @@ -844,12 +844,9 @@ mod tests { self.send.send(Event::Send(msg)).unwrap(); } - pub fn send_record(&mut self, record: R) - where - R: HasRType + AsRef<[u8]> + Clone + Send + 'static, - { + pub fn send_record(&mut self, record: R) { self.send - .send(Event::SendRecord(Box::new(record.clone()))) + .send(Event::SendRecord(RecordBuf::from(record))) .unwrap(); }