Release notes
Every Bodu release moves one or both of the two version streams, Stable and Preview, as versioning, stability, and support explains. This page says what to change when you upgrade and lists every release. Each release's full notes, with every fix and the issue behind it, are on its GitHub release.
Upgrading to 1.3.0
1.3.0 moves every Stable package to 1.3.0, promotes ten packages from the preview stream to Stable, and moves the three Experimental exchange-rate providers to 0.7.2. The 1.3.0 release notes list every change; this section covers what can need a change in your code.
Update your package references
- Move every Stable Bodu package to 1.3.0 in the same change. That includes
Bodu.Core1.0.1,Bodu.Security.Cryptography1.2.0, andBodu.Globalization.Calendar1.0.1, which shipped ahead of the lock-step version and rejoin it here. - Ten packages move from 0.7.1 to 1.3.0:
Bodu.IO.Pst,Bodu.Formats.Outlook,Bodu.Formats.Outlook.Msg,Bodu.Formats.Outlook.Pst, and the BoE, ECB, RBA, Fixer, exchangerate.host, and FRED exchange-rate providers. From 1.3.0 they keep the Stable promise; their changes since 0.7.1, breaking ones included, are listed below. - The IMF, Yahoo, and OFX providers move to 0.7.2. They are now Experimental, because each reads a feed its operator does not publish as an API, and they depend on the 1.3.0 Stable packages.
Breaking changes
| Package | What changed | What to do |
|---|---|---|
Bodu.Core, Bodu.Globalization.Calendar, Bodu.Globalization.Calendar.Builder |
WeekPattern is replaced by DayOfWeekSet, and every member that took or returned a WeekPattern takes or returns a DayOfWeekSet. Text that a WeekPattern wrote, calendar documents' workingDays attributes, and compiled .bcal packs read unchanged. |
Follow the migration table. A WeekPattern.ToByte() value stored elsewhere held Sunday at bit 6; DayOfWeekSet holds it at bit 0. |
Bodu.Text.Bencode |
A literal null passed to BencodeElement.GetProperty or TryGetProperty no longer compiles: the new UTF-8 overloads make it ambiguous. |
Cast the null to string. |
Bodu.IO.Pst (against 0.7.1) |
PstNode.Id and ParentId are renamed NodeId and ParentNodeId, and the PstFileException(message, innerException, error) constructor is removed. |
Use the new names, and the (message, error, innerException) constructor. |
Bodu.Financial.ExchangeRates.Boe, .Ecb, .Rba (against 0.7.1) |
Each options type derives from WebRateProviderOptions. The endpoint settings become BaseAddress, HttpTimeout, and UserAgent; BoeEndpointOptions and EcbEndpointOptions are removed; the BoE's OnDemandWindowDays becomes DefaultLookback and the RBA's CurrentEraRefreshInterval becomes RefreshInterval. The configuration keys follow the members. The three file-cache types are internal. |
Rename the keys in your configuration, as the provider configuration guide shows. Every option keeps its default. |
Behavior changes to check
These changes need no code change to compile, but they can change what your code sees at run time.
- The format libraries reject input they accepted. The readers and serializers for Bencode, TOML, YAML, CSV, dotenv, INI, and EditorConfig, and the compound-file,
.xls,.msg, and.pstreaders, were held to the defect fixes in other libraries' release notes, and fix what that found. Some malformed input that 1.0 read now fails with the format's exception, and some valid input reads differently. See conformance and test vectors for how each reader is held to its specification. - The serializers are stricter about types and values.
- An integer outside the range of an enum's underlying type is a serialization error, where it was narrowed into another value.
- A string enum converter created with
allowIntegerValues: falsereads and writes names only, as System.Text.Json's does. - Combined flags, renamed members, and enum dictionary keys are written and read as System.Text.Json writes and reads them, so the text for a flags value or a renamed member can change.
- The DotEnv and INI serializers reject a scalar root, such as a
decimalor aDateOnly. - The Delimited serializer rejects a record type that is a scalar or a collection.
- The Delimited and DotEnv serializers reject a type with a member that is not a scalar, on read as on write.
- Exceptions change type.
Bodu.Formats.Outlook.Pstreports a fault in the.pstcontainer asOutlookPstFormatException, with the container'sPstFileExceptionas its inner exception, so onecatch (OutlookFormatException)covers the.msgand.pstreaders.- The calendar loader reports more malformed documents as load diagnostics, so
LoadthrowsNotableDateValidationExceptionwhere another exception escaped, andTryLoadreturnsfalse. ThrowHelper.ThrowIfNotEqual<T>throwsArgumentOutOfRangeException, a subclass of theArgumentExceptionit threw.- See errors and exceptions for each package's exception family.
- Exchange-rate defaults change.
- The undated lookups of
CachingRateProviderandAggregatingRateProviderreturn the most recent rate on or before today, as the web providers do, where they required a rate dated today. - Today's rates are fetched again after
WebRateProviderOptions.RefreshInterval, 12 hours by default. - The named
HttpClientthat eachAdd<Source>ExchangeRatesregisters is capped atMaxResponseContentBufferSize, 64 MiB by default. - The per-observation and cache hit-and-miss log events default to
Trace. - exchangerate.host's default range path is
timeframe, and Yahoo dates each daily bar in the exchange's time zone.
- The undated lookups of
AddCachedNotableDateServicedecorates only the unkeyed service. KeyedINotableDateServiceregistrations stay in place, undecorated; see dependency injection and configuration.- Trimmed and native-AOT applications see new warnings. The Bencode and YAML serializers, and the JSON converter factories of
Bodu.Numerics.Serialization.JsonandBodu.Financial.Serialization.Json, declare[RequiresUnreferencedCode]or[RequiresDynamicCode], so a call to them reports IL2026 or IL3050. Trimming and native AOT gives the alternatives.
What is new
- Calendar value sets in
Bodu.Core:MonthSet,DayOfMonthSet,HourSet,MinuteSet,SecondSet, andDayOfWeekSet, behind one interface. See calendar value sets. - Recurrence: sub-daily rules (
FREQ=HOURLY,MINUTELY,SECONDLY) are enumerated, cron accepts the Quartz day tokensL,W,#, and?, and the rule builder takes the calendar value sets. See sub-daily frequencies and the Quartz day tokens. - Salvage reads of damaged
.pststores, which leave out a value whose reference does not resolve instead of failing the object. See salvaging a damaged store. - Smaller additions: Bencode dictionary keys by their bytes,
LoadJsonoverloads that take an algorithm registry,ConfigurationKeyOptions.LowercaseKeys, the Delimited writer'sCommentChar, Base58's Flickr alphabet, andWebRateProviderOptions.RefreshInterval. - Faster: recurrence queries no longer replay a series from its start, the BLAKE2 and BLAKE3 kernels shorten each round's critical path, and Argon2 rotates with a single AVX-512 instruction where the processor has one, with output unchanged bit for bit.
Release history
| Release | Published | What it shipped |
|---|---|---|
| 1.3.0 | This release | Every Stable package at 1.3.0, ten packages promoted to Stable, and the Experimental providers at 0.7.2, as above. |
Bodu.Globalization.Calendar 1.0.1 |
2026-10-01 | Out of band: working-day lookups no longer overflow the stack. |
Bodu.Core 1.0.1 and Bodu.Security.Cryptography 1.2.0 |
2026-10-01 | Out of band: further cryptography speed-ups, with the Bodu.Core internals they call. |
Bodu.Security.Cryptography 1.1.0 |
2026-09-29 | Out of band: Argon2 and cryptography speed-ups, and two conformance fixes after which data that AES-256-GCM-SIV sealed, and that AES-SIV sealed with an empty plaintext, in earlier releases does not decrypt. See AEAD modes. |
| 1.0.0 | 2026-09-24 | The Stable stream at 1.0.0 and the preview stream at 0.7.1; every library targets net8.0 and net10.0; ArrayExtensions.Reverse is renamed ToReversed. |
| 0.7.0 | 2026-09-24 | 14 packages: the exchange-rate infrastructure, its dependency injection, nine providers, and the three caching packages. |
| 0.6.0 | 2026-09-24 | 17 packages: the financial core, the calendar engine with its data packs and companions, recurrence, and the configuration bridge. |
| 0.5.0 | 2026-09-23 | 25 packages: the foundation libraries, the format and text libraries, and the .pst readers. |
Where to go next
- Versioning, stability, and support - the two streams, the tiers, and which releases receive fixes.
- Package matrix - every package with its tier and version.
- Getting started - install commands and a first sample from each library.