Skip to content

Clean up public API for v1.0.0 release#1024

Merged
popematt merged 4 commits into
amazon-ion:mainfrom
popematt:api-stabilization
Jun 11, 2026
Merged

Clean up public API for v1.0.0 release#1024
popematt merged 4 commits into
amazon-ion:mainfrom
popematt:api-stabilization

Conversation

@popematt

@popematt popematt commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Reduces the public API surface in preparation for v1.0.0. The goal is a minimal stable surface that we can grow from.
Items can always be added in minor releases but cannot be removed after 1.0.

This PR contains three commits:

  1. 79484b5 — Gate, remove, or reorganize public API items
  2. f9858cb — Remove arithmetic trait impls from numeric types
  3. 8bf799c — Gate chrono conversions behind experimental-chrono

If you're interested, the full output of cargo public-api is available here, but what follows is a summary of the changes and the reasoning for each.


Gate reader/writer-only types behind experimental-reader-writer (79484b5)

Several types were unconditionally public despite being useless without the streaming Reader/Writer. Consistent with the approach established in #576:

  • AnyEncoding — only meaningful when constructing a Reader
  • ElementReader, ElementWriter — only have implementations when
    the Reader/Writer is available
  • SymbolId — no stable API method accepts or returns it
  • Catalog, EmptyCatalog, MapCatalog — only consumed by Reader
  • SharedSymbolTable — only useful with catalogs

Gate tooling types behind experimental-tooling-apis (79484b5)

HasRange, HasSpan, and Span expose encoding-level byte details.
Every implementor is already behind this feature flag, and users who need position info have SourceLocation in the stable API (#810).

Remove vestigial items (79484b5)

Restrict visibility of implementation details (79484b5)

  • OwnedSequenceIterator — users receive it via IntoIterator, never need to name it
  • WriteConfig<*Encoding_1_1>::new() — Ion 1.1 types not accessible without their feature flag

Fix un-nameable types in public signatures (79484b5)

Clean up decimal module exports (79484b5)

  • Coefficient and Sign moved to ion_rs::decimal::Coefficient
    and ion_rs::decimal::Sign
  • coefficient submodule now pub(crate)

Remove leaked trait bounds from ConversionOperationError (79484b5)

Internal traits (ValueTypeExpectation, TypeExpectation) removed
from the struct definition; moved to impl blocks only.

Prevent implicit feature flags (79484b5)

digest and sha2 changed to dep:digest, dep:sha2 so they can
only be enabled via experimental-ion-hash.

Remove arithmetic traits from Int, UInt, Decimal (f9858cb)

Add, Sub, Neg, and num_traits::Zero were unused outside of
tests and exposed num_traits as a public dependency. Issues #970
and #286 ask for arithmetic but have no design resolution —
committing now would lock in a premature decision. Inherent
is_zero() methods replace Zero::is_zero().

Gate chrono behind experimental-chrono (8bf799c)

Chrono is an implementation detail (#838) that coupled ion-rs's
SemVer to chrono's. All From/TryInto impls between Timestamp
and chrono types now require the feature flag. Internal code uses
pub(crate) helper methods.

Potential correctness concern: The From<NaiveDateTime> conversion
is semantically suspect — Ion timestamps with unknown offset still
represent UTC instants, but NaiveDateTime carries no UTC guarantee.
This should be investigated before promoting the feature out of
experimental.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

popematt added 3 commits June 5, 2026 11:32
Gate items behind feature flags, remove vestigial types, fix
un-nameable types in public signatures, and clean up re-exports.

- Gate `AnyEncoding`, `ElementReader`, `ElementWriter`, `SymbolId`,
  `Catalog`, `EmptyCatalog`, `MapCatalog`, `SharedSymbolTable` behind
  `experimental-reader-writer`
- Gate `HasRange`, `HasSpan`, `Span` behind `experimental-tooling-apis`
- Remove `Format` enum and `IonResultIterExt` trait
- Restrict `OwnedSequenceIterator` and `WriteConfig<*_1_1>::new()`
  visibility to `pub(crate)`
- Re-export `SourceLocation` and `IonInput` at crate root
- Move `Coefficient` and `Sign` to `ion_rs::decimal::*`, make
  `coefficient` submodule `pub(crate)`
- Remove trait bounds from `ConversionOperationError` struct definition
- Change `dep:digest`, `dep:sha2` to prevent implicit feature flags
- Document public fields on `List`, `SExp`, `Blob`, `Clob`
- Document `IonInput` as sealed
- Define local `Format` enum in test harness (removed from public API)
These expose `num_traits` as a public dependency and lock in
premature arithmetic semantics. Replace `Zero::is_zero()` with
inherent methods. Arithmetic can be re-added in a minor release
once the design is resolved (amazon-ion#970, amazon-ion#286).

Verified: neither `ion-cli` nor `ion-schema-rust` uses any of
these operations.
Chrono is an implementation detail (amazon-ion#838) that should not couple
ion-rs's SemVer to chrono's. All `From`/`TryInto` impls between
`Timestamp` and chrono types now require the `experimental-chrono`
feature flag.

Internal code uses `pub(crate)` helper methods instead of the
trait impls.
@popematt popematt requested a review from almann June 5, 2026 22:22
@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.06%. Comparing base (2b0df7f) to head (b780cbf).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/result/conversion.rs 0.00% 6 Missing ⚠️
src/types/timestamp.rs 93.47% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1024      +/-   ##
==========================================
- Coverage   79.16%   79.06%   -0.11%     
==========================================
  Files         140      140              
  Lines       34932    34809     -123     
  Branches    34932    34809     -123     
==========================================
- Hits        27654    27520     -134     
- Misses       5187     5209      +22     
+ Partials     2091     2080      -11     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@almann almann left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good--though I see some unused imports that might need conditional compilation to make them not complain.

Comment on lines -272 to -283
#[test]
fn demonstrate_try_filter_and_try_map() -> IonResult<()> {
let mut reader = Reader::new(AnyEncoding, r#"1 2 3 4 5 6 7 8 9 10"#)?;
let evens: IonResult<Vec<i64>> = reader
.try_filter(|element| Ok(element.ion_type() == IonType::Int))
.try_map(|element| element.read()?.clone().expect_i64())
.try_filter(|i| Ok(i % 2 == 0))
.collect();
drop(reader);
assert_eq!(vec![2, 4, 6, 8, 10], evens?);
Ok(())
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these tests redundant and that is why they are removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They were demonstrating the IonResultIterExt trait, which is being removed.

Comment thread src/lazy/reader.rs
Comment on lines -184 to -190
/// Extension methods for iterators that return an `IonResult`.
///
/// These methods are analogous to methods that already exist on `Iterator`,
/// but automatically handle situations where the input `IonResult` is an `Err`
/// sparing the user from writing more boilerplate.
// This code is not used within the library but is intentionally available to tests and applications.
pub trait IonResultIterExt<Item>: Iterator<Item = IonResult<Item>> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we at all concerned about breaking any downstream with this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trait has a pretty distinctive name, so I checked GitHub and Amazon internal code, and no one names or uses this trait.

If someone is using it in private code, they can either let us know (and we can re-add it) or recreate it themselves. If there is any breakage, it will be at compile time and easy enough to fix (unlike other languages where this sort of change might cause a runtime failure).

Comment thread src/types/timestamp.rs Outdated
Comment thread src/types/timestamp.rs
Comment thread src/types/timestamp.rs Outdated
Comment thread src/types/timestamp.rs Outdated
@popematt popematt force-pushed the api-stabilization branch from 9074c1a to b780cbf Compare June 11, 2026 19:11
@popematt popematt merged commit f57dcee into amazon-ion:main Jun 11, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants