From 9501cd21113258a8510c42e0b7f6d6a980e49402 Mon Sep 17 00:00:00 2001 From: Zack Slayton Date: Fri, 7 Jul 2023 00:53:49 -0400 Subject: [PATCH] Module cleanup, adds `Element::expect_*`, removes `IntAccess` (#595) --- examples/read_all_values.rs | 8 +- src/binary/binary_writer.rs | 2 +- src/binary/decimal.rs | 2 +- src/binary/header.rs | 2 +- src/binary/int.rs | 9 +- src/binary/non_blocking/binary_buffer.rs | 3 +- src/binary/non_blocking/raw_binary_reader.rs | 8 +- src/binary/non_blocking/type_descriptor.rs | 2 +- src/binary/raw_binary_writer.rs | 6 +- src/binary/timestamp.rs | 11 +- src/binary/type_code.rs | 2 +- src/binary/uint.rs | 12 +- src/blocking_reader.rs | 3 +- src/element/annotations.rs | 2 +- src/element/builders.rs | 47 +++--- src/element/element_stream_reader.rs | 9 +- src/element/element_stream_writer.rs | 13 +- src/element/mod.rs | 151 +++++++++++++++++-- src/element/reader.rs | 6 +- src/{types => element}/sequence.rs | 0 src/element/writer.rs | 4 +- src/ion_data/ion_ord.rs | 3 +- src/ion_hash/representation.rs | 5 +- src/ion_hash/type_qualifier.rs | 4 +- src/ion_reader.rs | 3 +- src/ion_writer.rs | 5 +- src/lazy/binary/lazy_reader.rs | 3 +- src/lazy/binary/system/lazy_sequence.rs | 8 +- src/lazy/binary/system/lazy_struct.rs | 14 +- src/lazy/binary/system/lazy_system_reader.rs | 3 +- src/lazy/binary/system/lazy_value.rs | 18 +-- src/lib.rs | 74 ++++----- src/{result => }/position.rs | 0 src/raw_reader.rs | 6 +- src/raw_symbol_token.rs | 2 +- src/raw_symbol_token_ref.rs | 3 +- src/reader.rs | 5 +- src/result/incomplete.rs | 2 +- src/result/mod.rs | 25 +-- src/symbol_table.rs | 2 +- src/system_reader.rs | 3 +- src/text/non_blocking/raw_text_reader.rs | 7 +- src/text/non_blocking/text_buffer.rs | 2 +- src/text/parsers/decimal.rs | 2 +- src/text/parsers/timestamp.rs | 5 +- src/text/raw_text_writer.rs | 6 +- src/text/text_formatter.rs | 7 +- src/text/text_value.rs | 2 +- src/text/text_writer.rs | 2 +- src/tokens/mod.rs | 7 +- src/tokens/reader_stream.rs | 4 +- src/tokens/stream_reader.rs | 7 +- src/types/bytes.rs | 6 +- src/types/decimal/coefficient.rs | 4 +- src/types/decimal/mod.rs | 6 +- src/types/integer.rs | 130 +++++----------- src/types/list.rs | 13 +- src/types/lob.rs | 8 +- src/types/mod.rs | 9 +- src/types/sexp.rs | 13 +- src/types/struct.rs | 3 +- src/types/timestamp.rs | 93 ++++++------ tests/element_test_vectors.rs | 3 +- tests/ion_data_consistency.rs | 3 +- tests/ion_hash_tests.rs | 3 +- 65 files changed, 432 insertions(+), 403 deletions(-) rename src/{types => element}/sequence.rs (100%) rename src/{result => }/position.rs (100%) diff --git a/examples/read_all_values.rs b/examples/read_all_values.rs index bfa6e040..c5909a03 100644 --- a/examples/read_all_values.rs +++ b/examples/read_all_values.rs @@ -10,10 +10,10 @@ fn main() { #[cfg(feature = "experimental-reader")] mod example { - use ion_rs::IonResult; - use ion_rs::RawBinaryReader; - use ion_rs::RawStreamItem; - use ion_rs::{BlockingRawBinaryReader, IonReader, IonType, RawReader, StreamItem, UserReader}; + use ion_rs::{ + BlockingRawBinaryReader, IonReader, IonResult, IonType, RawBinaryReader, RawReader, + RawStreamItem, StreamItem, UserReader, + }; use memmap::MmapOptions; use std::fs::File; use std::process::exit; diff --git a/src/binary/binary_writer.rs b/src/binary/binary_writer.rs index 019840bf..17588686 100644 --- a/src/binary/binary_writer.rs +++ b/src/binary/binary_writer.rs @@ -3,8 +3,8 @@ use crate::constants::v1_0::system_symbol_ids; use crate::ion_writer::IonWriter; use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef}; use crate::result::{IonFailure, IonResult}; -use crate::types::{Decimal, Int, IonType, SymbolId, Timestamp}; use crate::SymbolTable; +use crate::{Decimal, Int, IonType, SymbolId, Timestamp}; use delegate::delegate; use std::io::Write; diff --git a/src/binary/decimal.rs b/src/binary/decimal.rs index 50b7424e..b4c1a0bd 100644 --- a/src/binary/decimal.rs +++ b/src/binary/decimal.rs @@ -12,8 +12,8 @@ use crate::binary::var_uint::VarUInt; use crate::ion_data::IonEq; use crate::result::{IonFailure, IonResult}; use crate::types::integer::UIntData; -use crate::types::{Coefficient, Decimal, Sign, UInt}; use crate::IonError; +use crate::{Coefficient, Decimal, Sign, UInt}; const DECIMAL_BUFFER_SIZE: usize = 32; const DECIMAL_POSITIVE_ZERO: Decimal = Decimal { diff --git a/src/binary/header.rs b/src/binary/header.rs index a593fbc0..8eb0a645 100644 --- a/src/binary/header.rs +++ b/src/binary/header.rs @@ -4,7 +4,7 @@ use crate::binary::constants::v1_0::length_codes; use crate::binary::nibbles::nibbles_from_byte; use crate::binary::IonTypeCode; use crate::result::IonResult; -use crate::types::IonType; +use crate::IonType; /// Contains all of the information that can be extracted from the one-octet type descriptor /// found at the beginning of each value in a binary Ion stream. diff --git a/src/binary/int.rs b/src/binary/int.rs index b105de41..f2410838 100644 --- a/src/binary/int.rs +++ b/src/binary/int.rs @@ -2,8 +2,7 @@ use std::mem; use crate::result::IonResult; use crate::types; -use crate::types::integer::Int; -use crate::types::Coefficient; +use crate::{Coefficient, Int}; use num_traits::Zero; use std::io::Write; @@ -102,9 +101,9 @@ impl DecodedInt { } impl From for Int { - /// Note that if the DecodedInt represents -0, converting it to an Integer will result in a 0. - /// If negative zero is significant to your use case, check it using [DecodedInt::is_negative_zero] - /// before converting it to an Integer. + // Note that if the DecodedInt represents -0, converting it to an Integer will result in a 0. + // If negative zero is significant to your use case, check it using [DecodedInt::is_negative_zero] + // before converting it to an Integer. fn from(uint: DecodedInt) -> Self { let DecodedInt { value, diff --git a/src/binary/non_blocking/binary_buffer.rs b/src/binary/non_blocking/binary_buffer.rs index 5bab8e99..1f250779 100644 --- a/src/binary/non_blocking/binary_buffer.rs +++ b/src/binary/non_blocking/binary_buffer.rs @@ -7,8 +7,7 @@ use crate::binary::uint::DecodedUInt; use crate::binary::var_int::VarInt; use crate::binary::var_uint::VarUInt; use crate::result::IonFailure; -use crate::types::Int; -use crate::{IonError, IonResult, IonType}; +use crate::{Int, IonError, IonResult, IonType}; use num_bigint::{BigInt, BigUint, Sign}; use std::io::Read; use std::mem; diff --git a/src/binary/non_blocking/raw_binary_reader.rs b/src/binary/non_blocking/raw_binary_reader.rs index 4921c7fb..2c41f20b 100644 --- a/src/binary/non_blocking/raw_binary_reader.rs +++ b/src/binary/non_blocking/raw_binary_reader.rs @@ -7,9 +7,9 @@ use crate::binary::var_uint::VarUInt; use crate::binary::IonTypeCode; use crate::ion_reader::IonReader; use crate::raw_reader::{BufferedRawReader, Expandable, RawStreamItem}; +use crate::raw_symbol_token::RawSymbolToken; use crate::result::IonFailure; -use crate::types::{Blob, Clob, Decimal, IntAccess, Str, SymbolId}; -use crate::{Int, IonError, IonResult, IonType, RawSymbolToken, Timestamp}; +use crate::{Blob, Clob, Decimal, Int, IonError, IonResult, IonType, Str, SymbolId, Timestamp}; use bytes::{BigEndian, ByteOrder}; use num_bigint::BigUint; use num_traits::Zero; @@ -876,8 +876,8 @@ impl + Expandable> IonReader for RawBinaryReader { fn read_i64(&mut self) -> IonResult { self.read_int().and_then(|i| { - i.as_i64() - .ok_or_else(|| IonError::decoding_error("integer was too large to fit in an i64")) + i64::try_from(i) + .map_err(|_| IonError::decoding_error("integer was too large to fit in an i64")) }) } diff --git a/src/binary/non_blocking/type_descriptor.rs b/src/binary/non_blocking/type_descriptor.rs index b1c0d630..e4739300 100644 --- a/src/binary/non_blocking/type_descriptor.rs +++ b/src/binary/non_blocking/type_descriptor.rs @@ -1,7 +1,7 @@ use crate::binary::constants::v1_0::length_codes; use crate::binary::nibbles::nibbles_from_byte; use crate::binary::IonTypeCode; -use crate::types::IonType; +use crate::IonType; /// Contains all of the information that can be extracted from the one-octet type descriptor /// found at the beginning of each value, annotations wrapper, IVM, or NOP in a binary Ion stream. diff --git a/src/binary/raw_binary_writer.rs b/src/binary/raw_binary_writer.rs index 4336cea9..2b90aa6a 100644 --- a/src/binary/raw_binary_writer.rs +++ b/src/binary/raw_binary_writer.rs @@ -13,8 +13,8 @@ use crate::ion_writer::IonWriter; use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef}; use crate::result::{IonFailure, IonResult}; use crate::types::integer::IntData; -use crate::types::{ContainerType, Decimal, Int, SymbolId, Timestamp}; -use crate::IonType; +use crate::types::ContainerType; +use crate::{Decimal, Int, IonType, SymbolId, Timestamp}; use super::decimal::DecimalBinaryEncoder; use super::timestamp::TimestampBinaryEncoder; @@ -910,7 +910,7 @@ mod writer_tests { use crate::ion_reader::IonReader; use crate::raw_symbol_token::{local_sid_token, RawSymbolToken}; use crate::reader::{Reader, ReaderBuilder, StreamItem}; - use crate::types::{Blob, Clob, Symbol}; + use crate::{Blob, Clob, Symbol}; use num_bigint::BigInt; use num_traits::Float; use std::convert::TryInto; diff --git a/src/binary/timestamp.rs b/src/binary/timestamp.rs index 56fe9b48..de0cd670 100644 --- a/src/binary/timestamp.rs +++ b/src/binary/timestamp.rs @@ -11,7 +11,8 @@ use crate::binary::raw_binary_writer::MAX_INLINE_LENGTH; use crate::binary::var_int::VarInt; use crate::binary::var_uint::VarUInt; use crate::result::IonResult; -use crate::types::{Decimal, Mantissa, Precision, Timestamp}; +use crate::types::{Mantissa, TimestampPrecision}; +use crate::{Decimal, Timestamp}; const MAX_TIMESTAMP_LENGTH: usize = 32; @@ -62,14 +63,14 @@ where bytes_written += VarUInt::write_u64(self, utc.year() as u64)?; // So far, we've written required fields. The rest are optional! - if timestamp.precision > Precision::Year { + if timestamp.precision > TimestampPrecision::Year { bytes_written += VarUInt::write_u64(self, utc.month() as u64)?; - if timestamp.precision > Precision::Month { + if timestamp.precision > TimestampPrecision::Month { bytes_written += VarUInt::write_u64(self, utc.day() as u64)?; - if timestamp.precision > Precision::Day { + if timestamp.precision > TimestampPrecision::Day { bytes_written += VarUInt::write_u64(self, utc.hour() as u64)?; bytes_written += VarUInt::write_u64(self, utc.minute() as u64)?; - if timestamp.precision > Precision::HourAndMinute { + if timestamp.precision > TimestampPrecision::HourAndMinute { bytes_written += VarUInt::write_u64(self, utc.second() as u64)?; if let Some(ref mantissa) = timestamp.fractional_seconds { // TODO: Both branches encode directly due to one diff --git a/src/binary/type_code.rs b/src/binary/type_code.rs index c38d682a..8f3fad62 100644 --- a/src/binary/type_code.rs +++ b/src/binary/type_code.rs @@ -2,7 +2,7 @@ use crate::IonResult; use std::convert::TryFrom; use crate::result::{IonError, IonFailure}; -use crate::types::IonType; +use crate::IonType; /// Represents the type information found in the header byte of each binary Ion value. /// While this value can be readily mapped to a user-level [`IonType`], it is a distinct concept. diff --git a/src/binary/uint.rs b/src/binary/uint.rs index 8ef3d4cc..cef2ebf9 100644 --- a/src/binary/uint.rs +++ b/src/binary/uint.rs @@ -4,7 +4,7 @@ use std::mem; use crate::result::IonResult; use crate::types::integer::UIntData; -use crate::types::{Int, UInt}; +use crate::{Int, UInt}; // This limit is used for stack-allocating buffer space to encode/decode UInts. const UINT_STACK_BUFFER_SIZE: usize = 16; @@ -116,16 +116,6 @@ impl AsRef<[u8]> for EncodedUInt { } /// Returns the magnitude as big-endian bytes. -/// -/// ``` -/// use ion_rs::binary::uint; -/// -/// let repr = uint::encode_u64(5u64); -/// assert_eq!(&[0x05], repr.as_bytes()); -/// -/// let two_bytes = uint::encode_u64(256u64); -/// assert_eq!(&[0x01, 0x00], two_bytes.as_bytes()); -/// ``` pub fn encode_u64(magnitude: u64) -> EncodedUInt { // We can divide the number of leading zero bits by 8 // to to get the number of leading zero bytes. diff --git a/src/blocking_reader.rs b/src/blocking_reader.rs index 4dfe38da..68b7b4de 100644 --- a/src/blocking_reader.rs +++ b/src/blocking_reader.rs @@ -3,12 +3,11 @@ use std::ops::Range; use crate::binary::non_blocking::raw_binary_reader::RawBinaryReader; use crate::data_source::IonDataSource; -use crate::element::{Blob, Clob}; use crate::ion_reader::IonReader; use crate::raw_reader::BufferedRawReader; use crate::result::IonResult; use crate::text::non_blocking::raw_text_reader::RawTextReader; -use crate::types::Timestamp; +use crate::{Blob, Clob, Timestamp}; use crate::{Decimal, Int, IonError, IonType, Str}; pub type BlockingRawTextReader = BlockingRawReader>, T>; diff --git a/src/element/annotations.rs b/src/element/annotations.rs index 58ebb376..25649f8b 100644 --- a/src/element/annotations.rs +++ b/src/element/annotations.rs @@ -10,7 +10,7 @@ use std::cmp::Ordering; /// things (including [`&str`] and [`String`]) into this sequence. /// /// ``` -/// use ion_rs::element::{Annotations, IntoAnnotations}; +/// use ion_rs::{Annotations, IntoAnnotations}; /// let annotations: Annotations = ["foo", "bar", "baz"].into_annotations(); /// for annotation in &annotations { /// assert_eq!(annotation.text().map(|s| s.len()), Some(3)); diff --git a/src/element/builders.rs b/src/element/builders.rs index 959a9f07..36d19cb6 100644 --- a/src/element/builders.rs +++ b/src/element/builders.rs @@ -1,11 +1,11 @@ -use crate::element::{Element, Sequence, Struct}; use crate::Symbol; +use crate::{Element, Sequence, Struct}; /// Constructs [Sequence], [List], and [SExp] values incrementally. /// /// Building a [Sequence]: /// ``` -/// use ion_rs::element::{Element, Sequence}; +/// use ion_rs::{Element, Sequence}; /// let actual: Sequence = Sequence::builder().push(1).push(true).push("foo").build(); /// let expected: Sequence = Sequence::new([ /// Element::integer(1), @@ -16,7 +16,7 @@ use crate::Symbol; /// ``` /// Building a [List]: /// ``` -/// use ion_rs::element::{Element, List, Sequence}; +/// use ion_rs::{Element, Sequence, List}; /// let actual: List = Sequence::builder() /// .push(1) /// .push(true) @@ -31,7 +31,7 @@ use crate::Symbol; /// ``` /// Building a [SExp]: /// ``` -/// use ion_rs::element::{Element, SExp, Sequence}; +/// use ion_rs::{Element, SExp, Sequence}; /// let actual: SExp = Sequence::builder() /// .push(1) /// .push(true) @@ -97,8 +97,7 @@ impl SequenceBuilder { /// Constructs [Struct] values incrementally. /// /// ``` -/// use ion_rs::element::Element; -/// use ion_rs::ion_struct; +/// use ion_rs::{Element, ion_struct}; /// let actual: Element = ion_struct! { /// "a": 1, /// "b": true, @@ -110,8 +109,7 @@ impl SequenceBuilder { /// ``` /// /// ``` -/// use ion_rs::element::{Element, Struct}; -/// use ion_rs::ion_struct; +/// use ion_rs::{Element, ion_struct, Struct}; /// let base_struct: Struct = ion_struct! { /// "foo": 1, /// "bar": 2, @@ -160,8 +158,7 @@ impl StructBuilder { /// Adds all of the provided `(name, value)` pairs to the [`Struct`] being constructed. /// /// ``` - /// use ion_rs::element::Element; - /// use ion_rs::ion_struct; + /// use ion_rs::{Element, ion_struct}; /// /// let struct1 = ion_struct! { /// "foo": 1, @@ -219,8 +216,7 @@ impl StructBuilder { /// Constructs a list [`Element`] with the specified child values. /// /// ``` -/// use ion_rs::element::Element; -/// use ion_rs::ion_list; +/// use ion_rs::{Element, ion_list}; /// // Construct a list Element from Rust values /// let actual: Element = ion_list!["foo", 7, false, ion_list![1.5f64, -8.25f64]].into(); /// // Construct an Element from serialized Ion data @@ -234,8 +230,7 @@ impl StructBuilder { /// /// ``` /// // Construct a list Element from existing Elements -/// use ion_rs::element::{Element, IntoAnnotatedElement}; -/// use ion_rs::ion_list; +/// use ion_rs::{Element, ion_list, IntoAnnotatedElement}; /// /// let string_element: Element = "foo".into(); /// let bool_element: Element = true.into(); @@ -256,7 +251,7 @@ impl StructBuilder { #[macro_export] macro_rules! ion_list { ($($element:expr),* $(,)?) => {{ - use $crate::element::Sequence; + use $crate::Sequence; Sequence::builder()$(.push($element))*.build_list() }}; } @@ -264,8 +259,7 @@ macro_rules! ion_list { /// Constructs an s-expression [`Element`] with the specified child values. /// /// ``` -/// use ion_rs::ion_sexp; -/// use ion_rs::element::Element; +/// use ion_rs::{Element, ion_sexp}; /// // Construct an s-expression Element from Rust values /// let actual: Element = ion_sexp!("foo" 7 false ion_sexp!(1.5f64 8.25f64)).into(); /// // Construct an Element from serialized Ion data @@ -279,8 +273,7 @@ macro_rules! ion_list { /// /// ``` /// // Construct a s-expression Element from existing Elements -/// use ion_rs::ion_sexp; -/// use ion_rs::element::{Element, IntoAnnotatedElement}; +/// use ion_rs::{Element, ion_sexp, IntoAnnotatedElement}; /// /// let string_element: Element = "foo".into(); /// let bool_element: Element = true.into(); @@ -300,7 +293,7 @@ macro_rules! ion_list { #[macro_export] macro_rules! ion_sexp { ($($element:expr)*) => {{ - use $crate::element::Sequence; + use $crate::Sequence; Sequence::builder()$(.push($element))*.build_sexp() }}; } @@ -311,8 +304,7 @@ macro_rules! ion_sexp { /// `Into`. /// /// ``` -/// use ion_rs::element::Element; -/// use ion_rs::{ion_struct, IonType}; +/// use ion_rs::{Element, ion_struct, IonType}; /// let field_name_2 = "x"; /// let prefix = "abc"; /// let suffix = "def"; @@ -340,7 +332,7 @@ macro_rules! ion_sexp { #[macro_export] macro_rules! ion_struct { ($($field_name:tt : $element:expr),* $(,)?) => {{ - use $crate::element::Struct; + use $crate::Struct; Struct::builder()$(.with_field($field_name, $element))*.build() }}; } @@ -351,8 +343,7 @@ macro_rules! ion_struct { /// `List` or `SExp`. /// /// ``` -/// use ion_rs::element::{Element, Sequence}; -/// use ion_rs::{ion_seq, ion_list}; +/// use ion_rs::{Element, ion_seq, ion_list, Sequence}; /// // Construct a Sequence from serialized Ion data /// let expected: Sequence = Element::read_all(r#" "foo" 7 false [1.5e0, -8.25e0] "#).unwrap(); /// // Construct a Sequence from Rust values @@ -367,16 +358,16 @@ macro_rules! ion_struct { #[macro_export] macro_rules! ion_seq { ($($element:expr),* $(,)?) => {{ - use $crate::element::Sequence; + use $crate::Sequence; Sequence::builder()$(.push($element))*.build() }}; ($($element:expr)*) => {{ - use $crate::element::Sequence; + use $crate::Sequence; Sequence::builder()$(.push($element))*.build() }}; } -use crate::types::{List, SExp}; +use crate::{List, SExp}; pub use {ion_list, ion_sexp, ion_struct}; #[cfg(test)] diff --git a/src/element/element_stream_reader.rs b/src/element/element_stream_reader.rs index 2747e2be..d8d56064 100644 --- a/src/element/element_stream_reader.rs +++ b/src/element/element_stream_reader.rs @@ -2,10 +2,11 @@ use crate::result::IonFailure; use crate::text::parent_container::ParentContainer; use crate::element::iterators::SymbolsIterator; -use crate::element::{Blob, Clob, Element}; +use crate::element::Element; use crate::ion_reader::IonReader; use crate::reader::StreamItem; -use crate::{Decimal, Int, IonError, IonResult, IonType, Str, Symbol, Timestamp}; +use crate::{Blob, Clob, Decimal, Int, Str, Symbol, Timestamp}; +use crate::{IonError, IonResult, IonType}; use std::fmt::Display; use std::mem; @@ -216,7 +217,7 @@ impl IonReader for ElementStreamReader { fn read_i64(&mut self) -> IonResult { match self.current_value.as_ref() { - Some(element) if element.as_int().is_some() => element.as_int().unwrap().expect_i64(), + Some(element) if element.as_int().is_some() => element.expect_i64(), _ => Err(self.expected("int value")), } } @@ -357,7 +358,7 @@ mod reader_tests { use super::*; use crate::ion_reader::IonReader; use crate::result::IonResult; - use crate::types::{Decimal, Timestamp}; + use crate::{Decimal, Timestamp}; use crate::IonType; diff --git a/src/element/element_stream_writer.rs b/src/element/element_stream_writer.rs index c1c0b355..61454cd7 100644 --- a/src/element/element_stream_writer.rs +++ b/src/element/element_stream_writer.rs @@ -1,12 +1,9 @@ use crate::element::builders::StructBuilder; -use crate::element::{Annotations, Element, IntoAnnotatedElement, Value}; use crate::ion_writer::IonWriter; -use crate::raw_symbol_token_ref::AsRawSymbolTokenRef; +use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef}; use crate::result::IonFailure; -use crate::types::Bytes; -use crate::{ - Decimal, Int, IonResult, IonType, RawSymbolTokenRef, Str, Symbol, SymbolTable, Timestamp, -}; +use crate::{Annotations, Element, IntoAnnotatedElement, Value}; +use crate::{Bytes, Decimal, Int, IonResult, IonType, Str, Symbol, SymbolTable, Timestamp}; // Represents a level into which the writer has stepped. // A writer that has not yet called step_in() is at the top level. @@ -300,13 +297,13 @@ where mod tests { use crate::element::element_stream_writer::ElementStreamWriter; - use crate::element::{Element, IntoAnnotatedElement, Value}; + use crate::{Element, IntoAnnotatedElement, Value}; use crate::element::builders::{SequenceBuilder, StructBuilder}; use crate::result::IonResult; use crate::ion_writer::IonWriter; - use crate::types::{Bytes, Timestamp}; + use crate::{Bytes, Timestamp}; use crate::{Decimal, IonType, Symbol}; #[track_caller] diff --git a/src/element/mod.rs b/src/element/mod.rs index 9edfcd1f..01c24ff8 100644 --- a/src/element/mod.rs +++ b/src/element/mod.rs @@ -19,27 +19,35 @@ use crate::ion_data::{IonEq, IonOrd}; use crate::ion_writer::IonWriter; use crate::text::text_formatter::IonValueFormatter; use crate::text::text_writer::TextWriterBuilder; -use crate::{ion_data, Decimal, Format, Int, IonResult, IonType, Str, Symbol, TextKind, Timestamp}; +use crate::{ + ion_data, Decimal, Format, Int, IonError, IonResult, IonType, Str, Symbol, TextKind, Timestamp, +}; use std::cmp::Ordering; use std::fmt::{Display, Formatter}; use std::io; mod annotations; -pub mod builders; -pub mod element_stream_reader; -pub mod element_stream_writer; pub(crate) mod iterators; + +pub mod builders; pub mod reader; pub mod writer; +#[cfg(feature = "experimental-reader")] +pub mod element_stream_reader; +#[cfg(feature = "experimental-writer")] +pub mod element_stream_writer; +mod sequence; + // Re-export the Value variant types and traits so they can be accessed directly from this module. use crate::data_source::IonDataSource; use crate::element::writer::ElementWriter; use crate::reader::ReaderBuilder; -pub use crate::types::{Blob, Bytes, Clob}; -pub use annotations::{Annotations, IntoAnnotations}; +use crate::{Blob, Bytes, Clob, List, SExp, Struct}; -pub use crate::types::{List, SExp, Sequence, Struct}; +use crate::result::IonFailure; +pub use annotations::{Annotations, IntoAnnotations}; +pub use sequence::Sequence; impl IonEq for Value { fn ion_eq(&self, other: &Self) -> bool { @@ -368,6 +376,14 @@ impl Element { } } + fn expected(&self, expected: IonType) -> IonError { + IonError::decoding_error(format!( + "expected a(n) {}, found a(n) {}", + expected, + self.ion_type() + )) + } + /// Returns a reference to this [Element]'s [Value]. /// /// ``` @@ -459,6 +475,24 @@ impl Element { } } + pub fn expect_int(&self) -> IonResult<&Int> { + self.as_int().ok_or_else(|| self.expected(IonType::Int)) + } + + pub fn as_i64(&self) -> Option { + match &self.value { + Value::Int(i) => i.as_i64(), + _ => None, + } + } + + pub fn expect_i64(&self) -> IonResult { + match &self.value { + Value::Int(i) => i.expect_i64(), + _ => Err(self.expected(IonType::Int)), + } + } + pub fn as_float(&self) -> Option { match &self.value { Value::Float(f) => Some(*f), @@ -466,6 +500,10 @@ impl Element { } } + pub fn expect_float(&self) -> IonResult { + self.as_float().ok_or_else(|| self.expected(IonType::Float)) + } + pub fn as_decimal(&self) -> Option<&Decimal> { match &self.value { Value::Decimal(d) => Some(d), @@ -473,6 +511,11 @@ impl Element { } } + pub fn expect_decimal(&self) -> IonResult<&Decimal> { + self.as_decimal() + .ok_or_else(|| self.expected(IonType::Decimal)) + } + pub fn as_timestamp(&self) -> Option<&Timestamp> { match &self.value { Value::Timestamp(t) => Some(t), @@ -480,6 +523,11 @@ impl Element { } } + pub fn expect_timestamp(&self) -> IonResult<&Timestamp> { + self.as_timestamp() + .ok_or_else(|| self.expected(IonType::Timestamp)) + } + pub fn as_text(&self) -> Option<&str> { match &self.value { Value::String(text) => Some(text.as_ref()), @@ -488,6 +536,15 @@ impl Element { } } + pub fn expect_text(&self) -> IonResult<&str> { + self.as_text().ok_or_else(|| { + IonError::decoding_error(format!( + "expected a text value, found a(n) {}", + self.ion_type() + )) + }) + } + pub fn as_string(&self) -> Option<&str> { match &self.value { Value::String(text) => Some(text.as_ref()), @@ -495,6 +552,11 @@ impl Element { } } + pub fn expect_string(&self) -> IonResult<&str> { + self.as_string() + .ok_or_else(|| self.expected(IonType::String)) + } + pub fn as_symbol(&self) -> Option<&Symbol> { match &self.value { Value::Symbol(sym) => Some(sym), @@ -502,6 +564,11 @@ impl Element { } } + pub fn expect_symbol(&self) -> IonResult<&Symbol> { + self.as_symbol() + .ok_or_else(|| self.expected(IonType::Symbol)) + } + pub fn as_bool(&self) -> Option { match &self.value { Value::Bool(b) => Some(*b), @@ -509,6 +576,10 @@ impl Element { } } + pub fn expect_bool(&self) -> IonResult { + self.as_bool().ok_or_else(|| self.expected(IonType::Bool)) + } + pub fn as_lob(&self) -> Option<&[u8]> { match &self.value { Value::Blob(bytes) | Value::Clob(bytes) => Some(bytes.as_ref()), @@ -516,6 +587,15 @@ impl Element { } } + pub fn expect_lob(&self) -> IonResult<&[u8]> { + self.as_lob().ok_or_else(|| { + IonError::decoding_error(format!( + "expected a lob value, found a(n) {}", + self.ion_type() + )) + }) + } + pub fn as_blob(&self) -> Option<&[u8]> { match &self.value { Value::Blob(bytes) => Some(bytes.as_ref()), @@ -523,6 +603,10 @@ impl Element { } } + pub fn expect_blob(&self) -> IonResult<&[u8]> { + self.as_blob().ok_or_else(|| self.expected(IonType::Blob)) + } + pub fn as_clob(&self) -> Option<&[u8]> { match &self.value { Value::Clob(bytes) => Some(bytes.as_ref()), @@ -530,6 +614,10 @@ impl Element { } } + pub fn expect_clob(&self) -> IonResult<&[u8]> { + self.as_clob().ok_or_else(|| self.expected(IonType::Clob)) + } + pub fn as_sequence(&self) -> Option<&Sequence> { match &self.value { Value::SExp(s) | Value::List(s) => Some(s), @@ -537,6 +625,37 @@ impl Element { } } + pub fn expect_sequence(&self) -> IonResult<&Sequence> { + self.as_sequence().ok_or_else(|| { + IonError::decoding_error(format!( + "expected a sequence value, found a(n) {}", + self.ion_type() + )) + }) + } + + pub fn as_list(&self) -> Option<&Sequence> { + match &self.value { + Value::List(s) => Some(s), + _ => None, + } + } + + pub fn expect_list(&self) -> IonResult<&Sequence> { + self.as_list().ok_or_else(|| self.expected(IonType::List)) + } + + pub fn as_sexp(&self) -> Option<&Sequence> { + match &self.value { + Value::SExp(s) => Some(s), + _ => None, + } + } + + pub fn expect_sexp(&self) -> IonResult<&Sequence> { + self.as_sexp().ok_or_else(|| self.expected(IonType::SExp)) + } + pub fn as_struct(&self) -> Option<&Struct> { match &self.value { Value::Struct(structure) => Some(structure), @@ -544,6 +663,11 @@ impl Element { } } + pub fn expect_struct(&self) -> IonResult<&Struct> { + self.as_struct() + .ok_or_else(|| self.expected(IonType::Struct)) + } + /// Reads a single Ion [`Element`] from the provided data source. /// /// If the data source is empty, returns `Ok(None)`. @@ -1045,8 +1169,7 @@ mod tests { } } - use crate::element::{Annotations, Element, IntoAnnotatedElement, Struct}; - use crate::types::IntAccess; + use crate::{Annotations, Element, IntoAnnotatedElement, Struct}; use num_bigint::BigInt; use std::collections::HashSet; use std::str::FromStr; @@ -1092,7 +1215,7 @@ mod tests { let expected: Element = 100i64.into(); assert_eq!(Some(&Int::from(100i64)), e.as_int()); assert_eq!(Some(100), e.as_i64()); - assert_eq!(None, e.as_big_int()); + assert_eq!(BigInt::from(100), BigInt::from(e.as_int().unwrap())); assert_eq!(&expected, e); }), } @@ -1106,7 +1229,10 @@ mod tests { op_assert: Box::new(|e: &Element| { let expected: Element = BigInt::from(100).into(); assert_eq!(Some(&Int::from(BigInt::from(100))), e.as_int()); - assert_eq!(BigInt::from_str("100").unwrap(), *e.as_big_int().unwrap()); + assert_eq!( + BigInt::from_str("100").unwrap(), + BigInt::from(e.as_int().unwrap()) + ); assert_eq!(&expected, e); }), } @@ -1275,7 +1401,6 @@ mod tests { Box::new(|e| { assert_eq!(None, e.as_int()); assert_eq!(None, e.as_i64()); - assert_eq!(None, e.as_big_int()); }), ), (AsF64, Box::new(|e| assert_eq!(None, e.as_float()))), @@ -1482,6 +1607,6 @@ mod value_tests { fn element_from_int(#[case] source_int: impl Into) { let int: Int = source_int.into(); let element: Element = int.clone().into(); - assert_eq!(element.as_int().unwrap().expect_i64(), int.expect_i64()) + assert_eq!(element.expect_i64(), int.expect_i64()) } } diff --git a/src/element/reader.rs b/src/element/reader.rs index 4aee4e99..d5efe808 100644 --- a/src/element/reader.rs +++ b/src/element/reader.rs @@ -3,11 +3,11 @@ //! Provides APIs to read Ion data into [Element] from different sources such //! as slices or files. -use crate::element::{Annotations, Element, Sequence, Struct, Value}; use crate::ion_reader::IonReader; use crate::reader::StreamItem; use crate::result::{IonFailure, IonResult}; use crate::Symbol; +use crate::{Annotations, Element, Sequence, Struct, Value}; /// Reads Ion data into [`Element`] instances. /// @@ -216,10 +216,10 @@ impl<'a, R: IonReader + ?Sized> ElementLoade #[cfg(test)] mod reader_tests { use super::*; - use crate::element::{Element, IntoAnnotatedElement}; use crate::ion_data::IonEq; - use crate::types::{Decimal, Timestamp}; use crate::{ion_list, ion_seq, ion_sexp, ion_struct}; + use crate::{Decimal, Timestamp}; + use crate::{Element, IntoAnnotatedElement}; use crate::{IonType, Symbol}; use num_bigint::BigInt; use rstest::*; diff --git a/src/types/sequence.rs b/src/element/sequence.rs similarity index 100% rename from src/types/sequence.rs rename to src/element/sequence.rs diff --git a/src/element/writer.rs b/src/element/writer.rs index bfeb4c05..b5407a8f 100644 --- a/src/element/writer.rs +++ b/src/element/writer.rs @@ -5,11 +5,11 @@ use crate::result::IonResult; -use crate::element::{Element, Value}; use crate::ion_writer::IonWriter; pub use crate::Format::*; use crate::IonType; pub use crate::TextKind::*; +use crate::{Element, Value}; /// Serializes [`Element`] instances into some kind of output sink. pub trait ElementWriter { @@ -91,9 +91,9 @@ where #[cfg(test)] mod tests { use crate::element::writer::ElementWriter; - use crate::element::{Element, List}; use crate::ion_data::IonEq; use crate::text::text_writer::TextWriterBuilder; + use crate::{Element, List}; use crate::ion_writer::IonWriter; use crate::{IonResult, IonType}; diff --git a/src/ion_data/ion_ord.rs b/src/ion_data/ion_ord.rs index 403ba18d..c9ab1939 100644 --- a/src/ion_data/ion_ord.rs +++ b/src/ion_data/ion_ord.rs @@ -61,8 +61,7 @@ pub(crate) fn ion_cmp_bool(this: &bool, that: &bool) -> Ordering { #[cfg(test)] mod ord_tests { use super::*; - use crate::element::{List, Sequence}; - use crate::{Element, IonData}; + use crate::{Element, IonData, List, Sequence}; use rstest::*; #[rstest] diff --git a/src/ion_hash/representation.rs b/src/ion_hash/representation.rs index c0bf7435..a3f78051 100644 --- a/src/ion_hash/representation.rs +++ b/src/ion_hash/representation.rs @@ -9,12 +9,11 @@ use crate::binary::decimal::DecimalBinaryEncoder; use crate::binary::timestamp::TimestampBinaryEncoder; use crate::binary::{self}; -use crate::element::{Element, Sequence, Struct}; use crate::ion_hash::element_hasher::ElementHasher; use crate::ion_hash::type_qualifier::type_qualifier_symbol; use crate::result::IonResult; -use crate::types::{Decimal, Int, IntAccess, Timestamp}; -use crate::{IonType, Symbol}; +use crate::{Decimal, Int, IonType, Struct, Symbol, Timestamp}; +use crate::{Element, Sequence}; use digest::{FixedOutput, Output, Reset, Update}; use num_bigint::BigInt; diff --git a/src/ion_hash/type_qualifier.rs b/src/ion_hash/type_qualifier.rs index e94dafe1..a3b80af6 100644 --- a/src/ion_hash/type_qualifier.rs +++ b/src/ion_hash/type_qualifier.rs @@ -3,8 +3,8 @@ //! //! [spec]: https://amazon-ion.github.io/ion-hash/docs/spec.html. use crate::binary::IonTypeCode; -use crate::element::{Element, Sequence, Struct}; -use crate::{Decimal, Int, IonType, Symbol, Timestamp}; +use crate::{Decimal, Int, IonType, Struct, Symbol, Timestamp}; +use crate::{Element, Sequence}; use std::slice; diff --git a/src/ion_reader.rs b/src/ion_reader.rs index ed1408d8..7a426a54 100644 --- a/src/ion_reader.rs +++ b/src/ion_reader.rs @@ -1,6 +1,5 @@ -use crate::element::{Blob, Clob}; use crate::result::IonResult; -use crate::types::{Decimal, Int, IonType, Str, Timestamp}; +use crate::{Blob, Clob, Decimal, Int, IonType, Str, Timestamp}; /** * This trait captures the format-agnostic parser functionality needed to navigate within an Ion diff --git a/src/ion_writer.rs b/src/ion_writer.rs index d20b68e0..1010f35e 100644 --- a/src/ion_writer.rs +++ b/src/ion_writer.rs @@ -1,6 +1,6 @@ use crate::raw_symbol_token_ref::AsRawSymbolTokenRef; use crate::result::IonResult; -use crate::types::{Decimal, Int, IonType, Timestamp}; +use crate::{Decimal, Int, IonType, Timestamp}; /** * This trait captures the format-agnostic encoding functionality needed to write native Rust types @@ -109,8 +109,7 @@ having to first drop the writer. feature = "experimental-writer", doc = r##" ``` -use ion_rs::element::Element; -use ion_rs::{IonResult, IonWriter, TextWriterBuilder}; +use ion_rs::{Element, IonResult, IonWriter, TextWriterBuilder}; # fn roundtrip() -> IonResult<()> { // Set up our output buffer let mut buffer: Vec = Vec::new(); diff --git a/src/lazy/binary/lazy_reader.rs b/src/lazy/binary/lazy_reader.rs index 5e67e09a..299fe655 100644 --- a/src/lazy/binary/lazy_reader.rs +++ b/src/lazy/binary/lazy_reader.rs @@ -24,8 +24,7 @@ use crate::{IonError, IonResult}; ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. -/// use ion_rs::element::Element; -/// use ion_rs::ion_list; +/// use ion_rs::{Element, ion_list}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = ion_list! [10, 20, 30].into(); diff --git a/src/lazy/binary/system/lazy_sequence.rs b/src/lazy/binary/system/lazy_sequence.rs index f85a8663..db7f7736 100644 --- a/src/lazy/binary/system/lazy_sequence.rs +++ b/src/lazy/binary/system/lazy_sequence.rs @@ -1,7 +1,7 @@ -use crate::element::{Annotations, Element, IntoAnnotatedElement, Sequence, Value}; use crate::lazy::binary::raw::lazy_raw_sequence::{LazyRawSequence, RawSequenceIterator}; use crate::lazy::binary::system::lazy_value::AnnotationsIterator; use crate::lazy::binary::system::lazy_value::LazyValue; +use crate::{Annotations, Element, IntoAnnotatedElement, Sequence, Value}; use crate::{IonError, IonResult, IonType, SymbolTable}; use std::fmt; use std::fmt::{Debug, Formatter}; @@ -15,8 +15,7 @@ use std::fmt::{Debug, Formatter}; ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. -/// use ion_rs::element::Element; -/// use ion_rs::ion_list; +/// use ion_rs::{Element, ion_list}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = ion_list! [10, 20, 30].into(); @@ -75,8 +74,7 @@ impl<'top, 'data> LazySequence<'top, 'data> { ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. - /// use ion_rs::ion_sexp; - /// use ion_rs::element::{Element, IntoAnnotatedElement}; + /// use ion_rs::{ion_sexp, Element, IntoAnnotatedElement}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = ion_sexp!(true false).with_annotations(["foo", "bar", "baz"]); diff --git a/src/lazy/binary/system/lazy_struct.rs b/src/lazy/binary/system/lazy_struct.rs index 5681f6c9..dbfae311 100644 --- a/src/lazy/binary/system/lazy_struct.rs +++ b/src/lazy/binary/system/lazy_struct.rs @@ -1,11 +1,12 @@ use crate::element::builders::StructBuilder; -use crate::element::{Annotations, Element, IntoAnnotatedElement, Struct}; use crate::lazy::binary::raw::lazy_raw_struct::{LazyRawStruct, RawStructIterator}; use crate::lazy::binary::system::lazy_value::AnnotationsIterator; use crate::lazy::binary::system::lazy_value::LazyValue; use crate::lazy::value_ref::ValueRef; use crate::result::IonFailure; -use crate::{IonError, IonResult, SymbolRef, SymbolTable}; +use crate::{ + Annotations, Element, IntoAnnotatedElement, IonError, IonResult, Struct, SymbolRef, SymbolTable, +}; use std::fmt; use std::fmt::{Debug, Formatter}; @@ -15,7 +16,7 @@ use std::fmt::{Debug, Formatter}; /// ``` ///# use ion_rs::IonResult; ///# fn main() -> IonResult<()> { -/// use ion_rs::element::Element; +/// use ion_rs::Element; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let ion_data = r#"{foo: 1, bar: 2, foo: 3, bar: 4}"#; @@ -78,7 +79,7 @@ impl<'top, 'data> LazyStruct<'top, 'data> { /// ``` ///# use ion_rs::IonResult; ///# fn main() -> IonResult<()> { - /// use ion_rs::element::Element; + /// use ion_rs::Element; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// use ion_rs::lazy::value_ref::ValueRef; /// @@ -116,7 +117,7 @@ impl<'top, 'data> LazyStruct<'top, 'data> { /// ``` ///# use ion_rs::IonResult; ///# fn main() -> IonResult<()> { - /// use ion_rs::element::Element; + /// use ion_rs::Element; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let ion_data = r#"{foo: "hello", bar: quux::5, baz: null, bar: false}"#; @@ -141,8 +142,7 @@ impl<'top, 'data> LazyStruct<'top, 'data> { /// ``` ///# use ion_rs::IonResult; ///# fn main() -> IonResult<()> { - /// use ion_rs::element::Element; - /// use ion_rs::IonType; + /// use ion_rs::{Element, IonType}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// use ion_rs::lazy::value_ref::ValueRef; /// diff --git a/src/lazy/binary/system/lazy_system_reader.rs b/src/lazy/binary/system/lazy_system_reader.rs index 1f6d7acc..20003096 100644 --- a/src/lazy/binary/system/lazy_system_reader.rs +++ b/src/lazy/binary/system/lazy_system_reader.rs @@ -38,8 +38,7 @@ const SYMBOLS: RawSymbolTokenRef = RawSymbolTokenRef::SymbolId(7); ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. -/// use ion_rs::element::Element; -/// use ion_rs::ion_list; +/// use ion_rs::{Element, ion_list}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = ion_list! [10, 20, 30].into(); diff --git a/src/lazy/binary/system/lazy_value.rs b/src/lazy/binary/system/lazy_value.rs index 82672d84..92c020df 100644 --- a/src/lazy/binary/system/lazy_value.rs +++ b/src/lazy/binary/system/lazy_value.rs @@ -1,10 +1,12 @@ -use crate::element::{Annotations, Element, IntoAnnotatedElement, Value}; use crate::lazy::binary::raw::lazy_raw_value::LazyRawValue; use crate::lazy::binary::raw::raw_annotations_iterator::RawAnnotationsIterator; use crate::lazy::value_ref::ValueRef; use crate::result::IonFailure; use crate::symbol_ref::AsSymbolRef; -use crate::{IonError, IonResult, IonType, RawSymbolTokenRef, SymbolRef, SymbolTable}; +use crate::{ + Annotations, Element, IntoAnnotatedElement, IonError, IonResult, IonType, RawSymbolTokenRef, + SymbolRef, SymbolTable, Value, +}; /// A value in a binary Ion stream whose header has been parsed but whose body (i.e. its data) has /// not. A `LazyValue` is immutable; its data can be read any number of times. @@ -17,8 +19,7 @@ use crate::{IonError, IonResult, IonType, RawSymbolTokenRef, SymbolRef, SymbolTa ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. -/// use ion_rs::element::Element; -/// use ion_rs::ion_list; +/// use ion_rs::{Element, ion_list}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = ion_list! [10, 20, 30].into(); @@ -70,8 +71,7 @@ impl<'top, 'data> LazyValue<'top, 'data> { ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. - /// use ion_rs::element::Element; - /// use ion_rs::IonType; + /// use ion_rs::{Element, IonType}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = "hello".into(); @@ -100,7 +100,7 @@ impl<'top, 'data> LazyValue<'top, 'data> { ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. - /// use ion_rs::element::{Element, IntoAnnotatedElement}; + /// use ion_rs::{Element, IntoAnnotatedElement}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// /// let element: Element = "hello".with_annotations(["foo", "bar", "baz"]); @@ -138,7 +138,7 @@ impl<'top, 'data> LazyValue<'top, 'data> { ///# fn main() -> IonResult<()> { /// /// // Construct an Element and serialize it as binary Ion. - /// use ion_rs::element::{Element, IntoAnnotatedElement}; + /// use ion_rs::{Element, IntoAnnotatedElement}; /// use ion_rs::lazy::binary::lazy_reader::LazyReader; /// use ion_rs::lazy::value_ref::ValueRef; /// @@ -359,10 +359,10 @@ impl<'top, 'data> TryFrom> for Annotations { #[cfg(test)] mod tests { - use crate::element::{Element, IntoAnnotatedElement}; use crate::lazy::binary::lazy_reader::LazyReader; use crate::lazy::binary::test_utilities::to_binary_ion; use crate::{ion_list, ion_sexp, ion_struct, Decimal, IonResult, IonType, Symbol, Timestamp}; + use crate::{Element, IntoAnnotatedElement}; use num_traits::Float; use rstest::*; diff --git a/src/lib.rs b/src/lib.rs index c98d90f0..1dfa0fd4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,8 +21,7 @@ //! ``` //! # use ion_rs::IonResult; //! # fn main() -> IonResult<()> { -//! use ion_rs::element::Element; -//! use ion_rs::IonType; +//! use ion_rs::{Element, IonType}; //! let ion_data = "[1, 2, 3]"; //! let element = Element::read_one(ion_data)?; //! assert_eq!(element.ion_type(), IonType::List); @@ -41,7 +40,7 @@ //! ``` //! # use ion_rs::IonResult; //! # fn main() -> IonResult<()> { -//! use ion_rs::element::Element; +//! use ion_rs::Element; //! //! let int: Element = 5.into(); //! assert_eq!(Element::read_one("5")?, int); @@ -67,8 +66,7 @@ //! ``` //! # use ion_rs::IonResult; //! # fn main() -> IonResult<()> { -//! use ion_rs::element::Element; -//! use ion_rs::{ion_list, ion_sexp, ion_struct}; +//! use ion_rs::{Element, ion_list, ion_sexp, ion_struct}; //! //! // Variable names are allowed //! let six = 6i64; @@ -95,7 +93,7 @@ //! ```no_run //! # use ion_rs::IonResult; //! # fn main() -> IonResult<()> { -//! use ion_rs::element::Element; +//! use ion_rs::Element; //! use std::fs::File; //! let ion_file = File::open("/foo/bar/baz.ion").unwrap(); //! // A simple pretty-printer @@ -111,8 +109,7 @@ //! ``` //! use ion_rs::IonResult; //! # fn main() -> IonResult<()> { -//! use ion_rs::element::{Element, Value}; -//! use ion_rs::{ion_list, ion_struct}; +//! use ion_rs::{Element, Value, ion_list, ion_struct}; //! let element: Element = ion_struct! { //! "foo": "hello", //! "bar": true, @@ -139,8 +136,7 @@ //! ``` //! use ion_rs::{Format, IonResult, TextKind}; //! # fn main() -> IonResult<()> { -//! use ion_rs::element::Element; -//! use ion_rs::{ion_list, ion_struct}; +//! use ion_rs::{Element, ion_list, ion_struct}; //! let element: Element = ion_struct! { //! "foo": "hello", //! "bar": true, @@ -165,57 +161,51 @@ #[allow(clippy::single_component_path_imports)] use rstest_reuse; -// This import is used in the doc comments and test code above. Clippy incorrectly -// declares it an unused import. -#[allow(unused_imports)] -use element::Element; - -pub mod binary; -pub mod result; -// Public as a workaround for: https://github.com/amazon-ion/ion-rust/issues/484 -pub mod constants; -pub mod data_source; -pub mod element; -pub(crate) mod raw_reader; -pub mod text; -pub mod types; - -mod ion_data; -#[cfg(feature = "ion-hash")] -pub mod ion_hash; - -pub(crate) mod blocking_reader; +// Private modules that serve to organize implementation details. +mod binary; +mod blocking_reader; mod catalog; - +mod constants; +mod data_source; +mod ion_data; mod ion_reader; mod ion_writer; +mod raw_reader; mod raw_symbol_token; mod raw_symbol_token_ref; -pub(crate) mod reader; +mod reader; mod shared_symbol_table; mod symbol_ref; mod symbol_table; mod system_reader; +mod text; + +// Publicly-visible modules with nested items which users may choose to import +pub mod element; +pub mod result; +pub mod types; + +#[cfg(feature = "ion-hash")] +pub mod ion_hash; #[cfg(feature = "experimental-lazy-reader")] pub mod lazy; // Experimental Streaming APIs +mod position; #[cfg(feature = "experimental-streaming")] pub mod thunk; #[cfg(feature = "experimental-streaming")] pub mod tokens; -#[doc(inline)] -pub use raw_symbol_token::RawSymbolToken; -#[doc(inline)] -pub use raw_symbol_token_ref::RawSymbolTokenRef; - +pub use element::{Annotations, Element, IntoAnnotatedElement, IntoAnnotations, Sequence, Value}; +pub use ion_data::IonData; pub use symbol_ref::SymbolRef; pub use symbol_table::SymbolTable; - -pub use types::{decimal::Decimal, Int, IonType, Str, Symbol, Timestamp}; - -pub use ion_data::IonData; +#[doc(inline)] +pub use types::{ + decimal::Decimal, Blob, Bytes, Clob, Coefficient, Int, IonType, List, SExp, Sign, Str, Struct, + Symbol, SymbolId, Timestamp, TimestampPrecision, UInt, +}; // These re-exports are only visible if the "experimental-reader" feature is enabled. #[cfg(feature = "experimental-reader")] @@ -224,6 +214,8 @@ pub use { blocking_reader::{BlockingRawBinaryReader, BlockingRawReader, BlockingRawTextReader}, ion_reader::IonReader, raw_reader::{BufferedRawReader, RawReader, RawStreamItem}, + raw_symbol_token::RawSymbolToken, + raw_symbol_token_ref::RawSymbolTokenRef, // Public as a workaround for: https://github.com/amazon-ion/ion-rust/issues/484 reader::integration_testing, reader::{Reader, ReaderBuilder, StreamItem, UserReader}, diff --git a/src/result/position.rs b/src/position.rs similarity index 100% rename from src/result/position.rs rename to src/position.rs diff --git a/src/raw_reader.rs b/src/raw_reader.rs index 4d0e3be9..6a29bb0a 100644 --- a/src/raw_reader.rs +++ b/src/raw_reader.rs @@ -1,8 +1,8 @@ -use crate::element::{Blob, Clob}; use crate::ion_reader::IonReader; use crate::raw_symbol_token::RawSymbolToken; -use crate::types::{IonType, Str}; -use crate::{Decimal, Int, IonResult, Timestamp}; +use crate::IonResult; +use crate::{Blob, Clob, Decimal, Int, Timestamp}; +use crate::{IonType, Str}; use std::fmt::{Display, Formatter}; use std::io::Read; diff --git a/src/raw_symbol_token.rs b/src/raw_symbol_token.rs index 7a55ae43..f30022c7 100644 --- a/src/raw_symbol_token.rs +++ b/src/raw_symbol_token.rs @@ -1,4 +1,4 @@ -use crate::types::SymbolId; +use crate::SymbolId; /// A symbol token encountered in a text or binary Ion stream. /// [RawSymbolToken]s do not store import source information for the token encountered. Similarly, diff --git a/src/raw_symbol_token_ref.rs b/src/raw_symbol_token_ref.rs index a6806b69..d4a00c4d 100644 --- a/src/raw_symbol_token_ref.rs +++ b/src/raw_symbol_token_ref.rs @@ -1,6 +1,5 @@ use crate::raw_symbol_token::RawSymbolToken; -use crate::types::SymbolId; -use crate::Symbol; +use crate::{Symbol, SymbolId}; /// Like RawSymbolToken, but the Text variant holds a borrowed reference instead of a String. #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/reader.rs b/src/reader.rs index efc2944a..5e192491 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -8,15 +8,14 @@ use crate::binary::constants::v1_0::IVM; use crate::binary::non_blocking::raw_binary_reader::RawBinaryReader; use crate::blocking_reader::{BlockingRawBinaryReader, BlockingRawTextReader}; use crate::data_source::IonDataSource; -use crate::element::{Blob, Clob}; use crate::ion_reader::IonReader; use crate::raw_reader::{Expandable, RawReader}; use crate::raw_symbol_token::RawSymbolToken; use crate::result::{IonFailure, IonResult}; use crate::symbol_table::SymbolTable; use crate::system_reader::SystemReader; -use crate::types::{Decimal, Int, Symbol, Timestamp}; use crate::IonType; +use crate::{Blob, Clob, Decimal, Int, Symbol, Timestamp}; use std::fmt::{Display, Formatter}; use crate::types::Str; @@ -132,6 +131,8 @@ pub mod integration_testing { use crate::raw_reader::RawReader; use crate::reader::{Reader, UserReader}; + pub use crate::binary::constants::v1_0::IVM; + pub fn new_reader<'a, R: 'a + RawReader>(raw_reader: R) -> Reader<'a> { UserReader::new(Box::new(raw_reader)) } diff --git a/src/result/incomplete.rs b/src/result/incomplete.rs index 47230805..2ea3de79 100644 --- a/src/result/incomplete.rs +++ b/src/result/incomplete.rs @@ -1,4 +1,4 @@ -use crate::result::position::Position; +use crate::position::Position; use thiserror::Error; #[derive(Clone, Debug, Error, PartialEq)] diff --git a/src/result/mod.rs b/src/result/mod.rs index bdb869a1..25d3a6a4 100644 --- a/src/result/mod.rs +++ b/src/result/mod.rs @@ -2,20 +2,21 @@ use std::convert::From; use std::fmt::{Debug, Error}; use std::{fmt, io}; -use crate::result::decoding_error::DecodingError; -use crate::result::encoding_error::EncodingError; -use crate::result::illegal_operation::IllegalOperation; -use crate::result::incomplete::IncompleteError; -use io_error::IoError; -use position::Position; use thiserror::Error; -pub mod decoding_error; -pub mod encoding_error; -pub mod illegal_operation; -pub mod incomplete; -pub mod io_error; -pub mod position; +mod decoding_error; +mod encoding_error; +mod illegal_operation; +mod incomplete; +mod io_error; + +pub use decoding_error::DecodingError; +pub use encoding_error::EncodingError; +pub use illegal_operation::IllegalOperation; +pub use incomplete::IncompleteError; +pub use io_error::IoError; + +use crate::position::Position; /// A unified Result type representing the outcome of method calls that may fail. pub type IonResult = Result; diff --git a/src/symbol_table.rs b/src/symbol_table.rs index 29a13c92..b0037f9f 100644 --- a/src/symbol_table.rs +++ b/src/symbol_table.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::sync::Arc; use crate::constants::v1_0; -use crate::types::{Symbol, SymbolId}; +use crate::{Symbol, SymbolId}; /// Stores mappings from Symbol IDs to text and vice-versa. // SymbolTable instances always have at least system symbols; they are never empty. diff --git a/src/system_reader.rs b/src/system_reader.rs index 5f3fe911..33fcbd0b 100644 --- a/src/system_reader.rs +++ b/src/system_reader.rs @@ -3,13 +3,12 @@ use std::ops::Range; use crate::binary::non_blocking::raw_binary_reader::RawBinaryReader; use crate::constants::v1_0::{system_symbol_ids, SYSTEM_SYMBOLS}; -use crate::element::{Blob, Clob}; use crate::ion_reader::IonReader; use crate::raw_reader::{Expandable, RawReader, RawStreamItem}; use crate::raw_symbol_token::RawSymbolToken; use crate::result::{IonError, IonFailure, IonResult}; use crate::system_reader::LstPosition::*; -use crate::types::{Decimal, Int, Str, Symbol, Timestamp}; +use crate::{Blob, Clob, Decimal, Int, Str, Symbol, Timestamp}; use crate::{IonType, SymbolTable}; /// Tracks where the [SystemReader] is in the process of reading a local symbol table. diff --git a/src/text/non_blocking/raw_text_reader.rs b/src/text/non_blocking/raw_text_reader.rs index b0dd930f..dd36afe2 100644 --- a/src/text/non_blocking/raw_text_reader.rs +++ b/src/text/non_blocking/raw_text_reader.rs @@ -1,13 +1,12 @@ use std::fmt::Display; -use crate::element::{Blob, Clob}; use crate::types::Str; use nom::Err::{Error, Failure, Incomplete}; use crate::ion_reader::IonReader; +use crate::position::Position; use crate::raw_reader::{BufferedRawReader, Expandable, RawStreamItem}; use crate::raw_symbol_token::RawSymbolToken; -use crate::result::position::Position; use crate::result::{IonError, IonFailure, IonResult}; use crate::text::non_blocking::text_buffer::TextBuffer; use crate::text::parent_container::ParentContainer; @@ -18,8 +17,8 @@ use crate::text::parsers::containers::{ }; use crate::text::parsers::top_level::{stream_item, RawTextStreamItem}; use crate::text::text_value::{AnnotatedTextValue, TextValue}; -use crate::types::{Decimal, Int, Timestamp}; use crate::IonType; +use crate::{Blob, Clob, Decimal, Int, Timestamp}; const INITIAL_PARENTS_CAPACITY: usize = 16; @@ -950,8 +949,8 @@ mod reader_tests { use crate::result::IonResult; use crate::text::non_blocking::raw_text_reader::RawTextReader; use crate::text::text_value::{IntoRawAnnotations, TextValue}; - use crate::types::{Decimal, Timestamp}; use crate::IonType; + use crate::{Decimal, Timestamp}; fn next_type + Expandable>( reader: &mut RawTextReader, diff --git a/src/text/non_blocking/text_buffer.rs b/src/text/non_blocking/text_buffer.rs index e3c778d8..0270eed2 100644 --- a/src/text/non_blocking/text_buffer.rs +++ b/src/text/non_blocking/text_buffer.rs @@ -1,4 +1,4 @@ -use crate::result::position::Position; +use crate::position::Position; use crate::IonResult; use std::io::Read; diff --git a/src/text/parsers/decimal.rs b/src/text/parsers/decimal.rs index d609db34..707b82ab 100644 --- a/src/text/parsers/decimal.rs +++ b/src/text/parsers/decimal.rs @@ -13,7 +13,7 @@ use crate::text::parsers::numeric_support::{ }; use crate::text::parsers::stop_character; use crate::text::text_value::TextValue; -use crate::types::{Coefficient, Decimal, Sign, UInt}; +use crate::{Coefficient, Decimal, Sign, UInt}; /// Matches the text representation of a decimal value and returns the resulting [Decimal] /// as a [TextValue::Decimal]. diff --git a/src/text/parsers/timestamp.rs b/src/text/parsers/timestamp.rs index 43c765ba..b56d1754 100644 --- a/src/text/parsers/timestamp.rs +++ b/src/text/parsers/timestamp.rs @@ -14,7 +14,8 @@ use crate::text::parse_result::{ }; use crate::text::parsers::{stop_character, trim_zeros_and_parse_i32, trim_zeros_and_parse_u32}; use crate::text::text_value::TextValue; -use crate::types::{Decimal, FractionalSecondSetter, Timestamp}; +use crate::types::FractionalSecondSetter; +use crate::{Decimal, Timestamp}; /// Matches the text representation of a timestamp value and returns the resulting Timestamp /// as a [TextValue::Timestamp]. @@ -281,7 +282,7 @@ mod reader_tests { use crate::text::parsers::timestamp::parse_timestamp; use crate::text::parsers::unit_test_support::{parse_test_err, parse_test_ok}; use crate::text::text_value::TextValue; - use crate::types::{Decimal, Timestamp}; + use crate::{Decimal, Timestamp}; fn parse_equals(text: &str, expected: Timestamp) { parse_test_ok(parse_timestamp, text, TextValue::Timestamp(expected)) diff --git a/src/text/raw_text_writer.rs b/src/text/raw_text_writer.rs index 4ef7212c..4d7449c8 100644 --- a/src/text/raw_text_writer.rs +++ b/src/text/raw_text_writer.rs @@ -3,12 +3,12 @@ use std::io::{BufWriter, Write}; use chrono::{DateTime, FixedOffset}; use crate::ion_writer::IonWriter; +use crate::raw_symbol_token::RawSymbolToken; use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef}; use crate::result::{IonFailure, IonResult}; use crate::text::text_formatter::STRING_ESCAPE_CODES; -use crate::types::{ContainerType, Decimal, Timestamp}; -use crate::TextKind; -use crate::{Int, IonType, RawSymbolToken}; +use crate::types::ContainerType; +use crate::{Decimal, Int, IonType, TextKind, Timestamp}; pub struct RawTextWriterBuilder { whitespace_config: WhitespaceConfig, diff --git a/src/text/text_formatter.rs b/src/text/text_formatter.rs index 04e5ee41..828e9fb5 100644 --- a/src/text/text_formatter.rs +++ b/src/text/text_formatter.rs @@ -1,6 +1,7 @@ -use crate::element::{Annotations, Sequence, Struct}; -use crate::raw_symbol_token_ref::AsRawSymbolTokenRef; -use crate::{Decimal, Int, IonResult, IonType, RawSymbolTokenRef, Timestamp}; +use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef}; +use crate::{Annotations, Sequence}; +use crate::{Decimal, Int, Struct, Timestamp}; +use crate::{IonResult, IonType}; pub const STRING_ESCAPE_CODES: &[&str] = &string_escape_code_init(); diff --git a/src/text/text_value.rs b/src/text/text_value.rs index 5d68a26e..fd915dab 100644 --- a/src/text/text_value.rs +++ b/src/text/text_value.rs @@ -1,6 +1,6 @@ use crate::raw_symbol_token::RawSymbolToken; -use crate::types::{Decimal, Int, Timestamp}; use crate::IonType; +use crate::{Decimal, Int, Timestamp}; #[derive(Debug, Clone, PartialEq)] pub(crate) struct AnnotatedTextValue { diff --git a/src/text/text_writer.rs b/src/text/text_writer.rs index a925afcc..7e03eee5 100644 --- a/src/text/text_writer.rs +++ b/src/text/text_writer.rs @@ -3,8 +3,8 @@ use crate::raw_symbol_token_ref::{AsRawSymbolTokenRef, RawSymbolTokenRef}; use crate::result::IonResult; use crate::text::raw_text_writer::RawTextWriter; use crate::text::raw_text_writer::RawTextWriterBuilder; -use crate::types::{Decimal, Timestamp}; use crate::TextKind; +use crate::{Decimal, Timestamp}; use crate::{Int, IonType, SymbolTable}; use delegate::delegate; use std::io::Write; diff --git a/src/tokens/mod.rs b/src/tokens/mod.rs index ade74bf0..8aa2982b 100644 --- a/src/tokens/mod.rs +++ b/src/tokens/mod.rs @@ -8,10 +8,11 @@ //! It pulls in parts of the [element crate](crate::element) API to make it easier to work //! with values without fully materializing the tree. -use crate::element::{Annotations, Bytes, Value}; use crate::result::IonFailure; use crate::text::text_formatter::IonValueFormatter; use crate::thunk::{Thunk, ThunkState}; +use crate::types::Bytes; +use crate::{Annotations, Value}; use crate::{Decimal, Int, IonError, IonResult, IonType, Str, Symbol, Timestamp}; use std::fmt::{Display, Formatter}; @@ -534,8 +535,8 @@ mod tests { } /// An arbitrary empty struct for testing the wrapper types. - fn empty_struct() -> crate::element::Struct { - crate::element::Struct::builder().build() + fn empty_struct() -> crate::Struct { + crate::Struct::builder().build() } #[rstest] diff --git a/src/tokens/reader_stream.rs b/src/tokens/reader_stream.rs index 72c685fe..13a48062 100644 --- a/src/tokens/reader_stream.rs +++ b/src/tokens/reader_stream.rs @@ -348,9 +348,9 @@ mod tests { use super::Instruction::*; use super::*; use crate::data_source::IonDataSource; - use crate::element::{Blob as ElemBlob, Clob as ElemClob}; use crate::tokens::{ContainerType, ScalarValue, Value}; - use crate::{Decimal, IonError, IonResult, ReaderBuilder, Symbol}; + use crate::{Blob as ElemBlob, Clob as ElemClob, Decimal, Symbol}; + use crate::{IonError, IonResult, ReaderBuilder}; use rstest::rstest; /// An arbitrary timestamp as a filler for testing purposes. diff --git a/src/tokens/stream_reader.rs b/src/tokens/stream_reader.rs index cae2f470..54ae274f 100644 --- a/src/tokens/stream_reader.rs +++ b/src/tokens/stream_reader.rs @@ -1,11 +1,12 @@ // Copyright Amazon.com, Inc. or its affiliates. use super::{ContainerType, Content, Instruction, Token, TokenStream}; -use crate::element::{Annotations, Blob, Clob}; +use crate::element::Annotations; use crate::result::{IonError, IonFailure}; use crate::tokens::ScalarValue; -use crate::types::IntAccess; -use crate::{Decimal, Int, IonReader, IonResult, IonType, Str, StreamItem, Symbol, Timestamp}; +use crate::{ + Blob, Clob, Decimal, Int, IonReader, IonResult, IonType, Str, StreamItem, Symbol, Timestamp, +}; use std::cell::RefCell; /// Adapts any [`TokenStream`] into an [`IonReader`]. diff --git a/src/types/bytes.rs b/src/types/bytes.rs index ebe184d0..f49e93ad 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -3,18 +3,18 @@ use std::cmp::Ordering; /// An owned, immutable byte array. /// ```rust -/// use ion_rs::element::Bytes; +/// use ion_rs::Bytes; /// let ivm: &[u8] = &[0xEA_u8, 0x01, 0x00, 0xE0]; // Ion 1.0 version marker /// let bytes: Bytes = ivm.into(); /// assert_eq!(&bytes, ivm); /// ``` /// ```rust -/// use ion_rs::element::Bytes; +/// use ion_rs::Bytes; /// let bytes: Bytes = "hello".into(); /// assert_eq!(&bytes, "hello".as_bytes()); /// ``` /// ```rust -/// use ion_rs::element::Bytes; +/// use ion_rs::Bytes; /// let bytes: Bytes = b"world".into(); /// assert_eq!(&bytes, b"world".as_slice()); /// ``` diff --git a/src/types/decimal/coefficient.rs b/src/types/decimal/coefficient.rs index a1a3074c..b3ef886a 100644 --- a/src/types/decimal/coefficient.rs +++ b/src/types/decimal/coefficient.rs @@ -4,8 +4,8 @@ use num_traits::Zero; use crate::result::{IonError, IonFailure}; use crate::types::decimal::magnitude::Magnitude; use crate::types::integer::UIntData; -use crate::types::{Int, UInt}; use crate::IonResult; +use crate::{Int, UInt}; use std::convert::TryFrom; use std::fmt::{Display, Formatter}; use std::ops::{MulAssign, Neg}; @@ -233,7 +233,7 @@ mod coefficient_tests { use std::ops::Neg; use std::str::FromStr; - use crate::types::{Coefficient, Decimal, Sign, UInt}; + use crate::{Coefficient, Decimal, Sign, UInt}; fn eq_test(c1: I1, c2: I2) where diff --git a/src/types/decimal/mod.rs b/src/types/decimal/mod.rs index 222a13e6..1416db0b 100644 --- a/src/types/decimal/mod.rs +++ b/src/types/decimal/mod.rs @@ -5,7 +5,7 @@ use num_bigint::{BigInt, BigUint, ToBigInt, ToBigUint}; use crate::ion_data::{IonEq, IonOrd}; use crate::result::{IonError, IonFailure}; use crate::types::integer::UIntData; -use crate::types::{Coefficient, Sign, UInt}; +use crate::{Coefficient, Sign, UInt}; use crate::{Int, IonResult}; use num_integer::Integer; use num_traits::{ToPrimitive, Zero}; @@ -24,7 +24,7 @@ mod magnitude; /// ``` /// # use ion_rs::IonResult; /// # fn main() -> IonResult<()> { -/// use ion_rs::types::{Int, Decimal, Sign, UInt}; +/// use ion_rs::{Int, Decimal, Sign, UInt}; /// // Equivalent to: 1225 * 10^-2, or 12.25 /// let decimal = Decimal::new(1225, -2); /// // The coefficient can be viewed as a sign/magnitude pair... @@ -496,7 +496,7 @@ impl Display for Decimal { #[cfg(test)] mod decimal_tests { use crate::result::IonResult; - use crate::types::{Coefficient, Decimal, Int, Sign, UInt}; + use crate::{Coefficient, Decimal, Int, Sign, UInt}; use num_bigint::{BigInt, BigUint}; use num_traits::Float; diff --git a/src/types/integer.rs b/src/types/integer.rs index a4d09ee2..cfad0e22 100644 --- a/src/types/integer.rs +++ b/src/types/integer.rs @@ -1,4 +1,3 @@ -use crate::element::Element; use crate::ion_data::{IonEq, IonOrd}; use crate::result::IonFailure; use crate::{IonError, IonResult}; @@ -8,58 +7,6 @@ use std::cmp::Ordering; use std::fmt::{Display, Formatter}; use std::ops::{Add, Neg}; -/// Provides convenient integer accessors for integer values that are like [`Int`] -pub trait IntAccess { - /// Returns the value as an `i64` if it can be represented as such. - /// - /// ## Usage - /// ``` - /// # use ion_rs::element::*; - /// # use ion_rs::types::*; - /// # use num_bigint::*; - /// let big_int = Int::from(BigInt::from(100)); - /// let i64_int = Int::from(100); - /// assert_eq!(big_int.as_i64(), i64_int.as_i64()); - /// - /// // works on element too - /// let big_elem: Element = big_int.into(); - /// let i64_elem: Element = i64_int.into(); - /// - /// assert_eq!(big_elem.as_i64(), i64_elem.as_i64()); - /// ``` - fn as_i64(&self) -> Option; - - /// Returns a reference as a [`BigInt`] if it is represented as such. Note that this - /// method may return `None` if the underlying representation *is not* stored in a [`BigInt`] - /// such as if it is represented as an `i64` so it is somewhat asymmetric with respect - /// to [`IntAccess::as_i64`]. - /// - /// ## Usage - /// ``` - /// # use ion_rs::element::*; - /// # use ion_rs::types::*; - /// # use num_bigint::*; - /// # use std::str::FromStr; - /// let big_int = Int::from(BigInt::from(100)); - /// assert_eq!( - /// BigInt::from_str("100").unwrap(), - /// *big_int.as_big_int().unwrap() - /// ); - /// let i64_int = Int::from(100); - /// assert_eq!(None, i64_int.as_big_int()); - /// - /// // works on element too - /// let big_elem: Element = big_int.into(); - /// assert_eq!( - /// BigInt::from_str("100").unwrap(), - /// *big_elem.as_big_int().unwrap() - /// ); - /// let i64_elem: Element = i64_int.into(); - /// assert_eq!(None, i64_elem.as_big_int()); - /// ``` - fn as_big_int(&self) -> Option<&BigInt>; -} - /// Represents a UInt of any size. Used for reading binary integers and symbol Ids. /// Used to represent the unsigned magnitude of Decimal values and fractional seconds. #[derive(Debug, Clone)] @@ -288,6 +235,33 @@ impl TryFrom<&Int> for UInt { } } +macro_rules! impl_small_signed_int_try_from_int { + ($($t:ty),*) => ($( + impl TryFrom for $t { + type Error = IonError; + + fn try_from(value: Int) -> Result { + match value.data { + IntData::I64(small_int) => <$t>::try_from(small_int).map_err(|_| { + IonError::illegal_operation(concat!("Int was too large to be converted to a(n) ", stringify!($t))) + }), + IntData::BigInt(big_int) => big_int.try_into().map_err(|_| { + IonError::illegal_operation(concat!("Int was too large to be converted to a(n) ", stringify!($t))) + }), + } + } + } + )*) +} + +impl_small_signed_int_try_from_int!(i8, i16, i32, i64, i128, isize); + +impl From<&Int> for BigInt { + fn from(value: &Int) -> Self { + value.clone().into() + } +} + #[inline(never)] fn big_integer_from_u64(value: u64) -> Int { IntData::BigInt(BigInt::from(value)).into() @@ -341,13 +315,19 @@ impl Int { } /// If this value is small enough to fit in an `i64`, returns `Ok(i64)`. Otherwise, - /// returns a [`DecodingError`](crate::IonError::Decoding). + /// returns a [`DecodingError`](IonError::Decoding). pub fn expect_i64(&self) -> IonResult { + self.as_i64().ok_or_else(|| { + IonError::decoding_error(format!("Int {self} is too large to fit in an i64.")) + }) + } + + /// If this value is small enough to fit in an `i64`, returns `Some(i64)`. Otherwise, returns + /// `None`. + pub fn as_i64(&self) -> Option { match &self.data { - IntData::I64(i) => Ok(*i), - IntData::BigInt(_) => { - IonResult::decoding_error(format!("Int {self} is too large to fit in an i64.")) - } + IntData::I64(i) => Some(*i), + IntData::BigInt(big_int) => big_int.to_i64(), } } @@ -372,24 +352,6 @@ impl Int { } } -impl IntAccess for Int { - #[inline] - fn as_i64(&self) -> Option { - match &self.data { - IntData::I64(i) => Some(*i), - IntData::BigInt(big) => big.to_i64(), - } - } - - #[inline] - fn as_big_int(&self) -> Option<&BigInt> { - match &self.data { - IntData::I64(_) => None, - IntData::BigInt(big) => Some(big), - } - } -} - impl PartialEq for Int { fn eq(&self, other: &Self) -> bool { use IntData::*; @@ -566,22 +528,6 @@ impl From for BigInt { } } -impl IntAccess for Element { - fn as_i64(&self) -> Option { - match self.as_int() { - Some(any) => any.as_i64(), - _ => None, - } - } - - fn as_big_int(&self) -> Option<&BigInt> { - match self.as_int() { - Some(any) => any.as_big_int(), - _ => None, - } - } -} - impl Display for Int { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { match &self.data { diff --git a/src/types/list.rs b/src/types/list.rs index 48ece72a..c9d959a6 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -1,15 +1,14 @@ use crate::element::builders::SequenceBuilder; use crate::element::iterators::SequenceIterator; -use crate::element::{Element, Sequence}; use crate::ion_data::IonEq; use crate::text::text_formatter::IonValueFormatter; +use crate::{Element, Sequence}; use delegate::delegate; use std::fmt::{Display, Formatter}; /// An in-memory representation of an Ion list. /// ``` -/// use ion_rs::element::Element; -/// use ion_rs::ion_list; +/// use ion_rs::{ion_list, Element}; /// # use ion_rs::IonResult; /// # fn main() -> IonResult<()> { /// let list = ion_list![1, 2, 3]; @@ -85,17 +84,17 @@ impl From for Sequence { #[cfg(test)] mod tests { - use crate::ion_list; - use crate::types::IntAccess; + use crate::{ion_list, IonResult}; #[test] - fn for_element_in_list() { + fn for_element_in_list() -> IonResult<()> { // Simple example to exercise List's implementation of IntoIterator let list = ion_list![1, 2, 3]; let mut sum = 0; for element in &list { - sum += element.as_i64().unwrap(); + sum += element.expect_int()?.expect_i64()?; } assert_eq!(sum, 6i64); + Ok(()) } } diff --git a/src/types/lob.rs b/src/types/lob.rs index 8622b61a..78429e50 100644 --- a/src/types/lob.rs +++ b/src/types/lob.rs @@ -1,16 +1,16 @@ -use crate::element::Bytes; +pub use crate::types::bytes::Bytes; /// An in-memory representation of an Ion blob. /// /// ```rust -/// use ion_rs::element::Blob; +/// use ion_rs::Blob; /// let ivm: &[u8] = &[0xEA_u8, 0x01, 0x00, 0xE0]; // Ion 1.0 version marker /// let blob: Blob = ivm.into(); /// assert_eq!(&blob, ivm); /// assert_eq!(blob.as_slice().len(), 4); /// ``` /// ```rust -/// use ion_rs::element::Blob; +/// use ion_rs::Blob; /// let blob: Blob = "hello".into(); /// assert_eq!(&blob, "hello".as_bytes()); /// assert_eq!(blob.as_slice().len(), 5); @@ -27,7 +27,7 @@ impl Blob { /// An in-memory representation of an Ion clob. /// /// ```rust -/// use ion_rs::element::Clob; +/// use ion_rs::Clob; /// let clob: Clob = "hello".into(); /// assert_eq!(&clob, "hello".as_bytes()); /// assert_eq!(clob.as_slice().len(), 5); diff --git a/src/types/mod.rs b/src/types/mod.rs index 495689cd..6c01a60a 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -9,27 +9,26 @@ pub(crate) mod decimal; pub(crate) mod integer; mod list; mod lob; -mod sequence; mod sexp; mod string; mod r#struct; mod symbol; mod timestamp; +pub use crate::element::Sequence; pub use crate::types::bytes::Bytes; pub use decimal::coefficient::{Coefficient, Sign}; pub use decimal::Decimal; -pub use integer::{Int, IntAccess, UInt}; +pub use integer::{Int, UInt}; pub use list::List; pub use lob::{Blob, Clob}; pub use r#struct::Struct; -pub use sequence::Sequence; pub use sexp::SExp; pub use string::Str; pub use symbol::Symbol; pub use timestamp::{ - DaySetter, FractionalSecondSetter, HourAndMinuteSetter, Mantissa, MonthSetter, Precision, - SecondSetter, Timestamp, + DaySetter, FractionalSecondSetter, HourAndMinuteSetter, Mantissa, MonthSetter, SecondSetter, + Timestamp, TimestampPrecision, }; use crate::ion_data::IonOrd; diff --git a/src/types/sexp.rs b/src/types/sexp.rs index d74dd752..f9cfc033 100644 --- a/src/types/sexp.rs +++ b/src/types/sexp.rs @@ -1,15 +1,14 @@ use crate::element::builders::SequenceBuilder; use crate::element::iterators::SequenceIterator; -use crate::element::{Element, Sequence}; use crate::ion_data::IonEq; use crate::text::text_formatter::IonValueFormatter; +use crate::{Element, Sequence}; use delegate::delegate; use std::fmt::{Display, Formatter}; /// An in-memory representation of an Ion s-expression /// ``` -/// use ion_rs::element::Element; -/// use ion_rs::ion_sexp; +/// use ion_rs::{Element, ion_sexp}; /// # use ion_rs::IonResult; /// # fn main() -> IonResult<()> { /// let sexp = ion_sexp!(1 2 3); @@ -85,17 +84,17 @@ impl From for Sequence { #[cfg(test)] mod tests { - use crate::ion_sexp; - use crate::types::IntAccess; + use crate::{ion_sexp, IonResult}; #[test] - fn for_element_in_sexp() { + fn for_element_in_sexp() -> IonResult<()> { // Simple example to exercise SExp's implementation of IntoIterator let sexp = ion_sexp!(1 2 3); let mut sum = 0; for element in &sexp { - sum += element.as_i64().unwrap(); + sum += element.expect_int()?.expect_i64()?; } assert_eq!(sum, 6i64); + Ok(()) } } diff --git a/src/types/struct.rs b/src/types/struct.rs index a866060f..d9e9a3a2 100644 --- a/src/types/struct.rs +++ b/src/types/struct.rs @@ -131,8 +131,7 @@ impl<'a> Iterator for FieldValuesIterator<'a> { /// An in-memory representation of an Ion Struct /// ``` -/// use ion_rs::element::Element; -/// use ion_rs::ion_struct; +/// use ion_rs::{Element, ion_struct}; /// # use ion_rs::IonResult; /// # fn main() -> IonResult<()> { /// let struct_ = ion_struct! { diff --git a/src/types/timestamp.rs b/src/types/timestamp.rs index d14f595e..6992ce51 100644 --- a/src/types/timestamp.rs +++ b/src/types/timestamp.rs @@ -15,7 +15,7 @@ use std::ops::Div; /// Indicates the most precise time unit that has been specified in the accompanying [Timestamp]. #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Default)] -pub enum Precision { +pub enum TimestampPrecision { /// Year-level precision (e.g. `2020T`) #[default] Year, @@ -153,27 +153,27 @@ fn datetime_at_offset(utc_datetime: &NaiveDateTime, seconds_east: i32) -> DateTi pub struct Timestamp { pub(crate) date_time: NaiveDateTime, pub(crate) offset: Option, - pub(crate) precision: Precision, + pub(crate) precision: TimestampPrecision, pub(crate) fractional_seconds: Option, } impl Timestamp { /// Converts a [`NaiveDateTime`] or [`DateTime`] to a Timestamp with the specified - /// precision. If the precision is [`Precision::Second`], nanosecond precision (the maximum + /// precision. If the precision is [`TimestampPrecision::Second`], nanosecond precision (the maximum /// supported by a [`Timelike`]) is assumed. - pub fn from_datetime(datetime: D, precision: Precision) -> Timestamp + pub fn from_datetime(datetime: D, precision: TimestampPrecision) -> Timestamp where D: Datelike + Timelike + Into, { let mut timestamp: Timestamp = datetime.into(); - if precision < Precision::Second { + if precision < TimestampPrecision::Second { timestamp.fractional_seconds = None; } timestamp.precision = precision; timestamp } - /// If the precision is [Precision::Second], returns the Decimal scale of this Timestamp's + /// If the precision is [TimestampPrecision::Second], returns the Decimal scale of this Timestamp's /// fractional seconds; otherwise, returns None. /// /// For example, a Timestamp with 553 milliseconds would return a Decimal scale of 3. @@ -192,7 +192,7 @@ impl Timestamp { } } - /// If the precision is [Precision::Second], returns a Decimal representation of this Timestamp's + /// If the precision is [TimestampPrecision::Second], returns a Decimal representation of this Timestamp's /// fractional seconds; otherwise, returns None. /// /// For example, a Timestamp with 553 milliseconds would return a Decimal with @@ -223,7 +223,7 @@ impl Timestamp { } } - /// If the precision is [Precision::Second], returns a u32 representing + /// If the precision is [TimestampPrecision::Second], returns a u32 representing /// this Timestamp's fractional seconds in nanoseconds; otherwise, returns None. /// /// NOTE: This is a potentially lossy operation. A Timestamp with picoseconds would return a @@ -269,7 +269,7 @@ impl Timestamp { } /// Tests the fractional seconds fields of two timestamps for ordering. This function will - /// only be called if both Timestamps have a precision of [Precision::Second]. + /// only be called if both Timestamps have a precision of [TimestampPrecision::Second]. fn fractional_seconds_compare(&self, other: &Timestamp) -> Ordering { use Mantissa::*; match ( @@ -305,7 +305,7 @@ impl Timestamp { } /// Tests the fractional seconds fields of two timestamps for equality. This function will - /// only be called if both Timestamps have a precision of [Precision::Second]. + /// only be called if both Timestamps have a precision of [TimestampPrecision::Second]. fn fractional_seconds_equal(&self, other: &Timestamp) -> bool { use Mantissa::*; @@ -433,21 +433,21 @@ impl Timestamp { write!(output, "{:0>4}", datetime.year())?; // ^-- 0-padded, right aligned, 4-digit year - if self.precision == Precision::Year { + if self.precision == TimestampPrecision::Year { write!(output, "T")?; return Ok(()); } write!(output, "-{:0>2}", datetime.month())?; // ^-- delimiting hyphen and 0-padded, right aligned, 2-digit month - if self.precision == Precision::Month { + if self.precision == TimestampPrecision::Month { write!(output, "T")?; return Ok(()); } write!(output, "-{:0>2}", datetime.day())?; // ^-- delimiting hyphen and 0-padded, right aligned, 2-digit day - if self.precision == Precision::Day { + if self.precision == TimestampPrecision::Day { write!(output, "T")?; return Ok(()); } @@ -459,7 +459,7 @@ impl Timestamp { datetime.hour(), datetime.minute() )?; - if self.precision == Precision::HourAndMinute { + if self.precision == TimestampPrecision::HourAndMinute { self.format_offset(offset_minutes, output)?; return Ok(()); } @@ -502,7 +502,7 @@ impl Timestamp { // // See [TimestampBuilder]'s documentation for more details. - /// Creates a TimestampBuilder with the specified year and [Precision::Year]. + /// Creates a TimestampBuilder with the specified year and [TimestampPrecision::Year]. pub fn with_year(year: u32) -> MonthSetter { let builder: TimestampBuilder = TimestampBuilder { year: year as u16, @@ -512,7 +512,7 @@ impl Timestamp { } /// Creates a TimestampBuilder with the specified year, month, and day. Its precision is - /// set to [Precision::Day]. + /// set to [TimestampPrecision::Day]. pub fn with_ymd(year: u32, month: u32, day: u32) -> HourAndMinuteSetter { let builder = Timestamp::with_year(year) .with_month(month) @@ -522,7 +522,7 @@ impl Timestamp { } /// Creates a TimestampBuilder with the specified year, month, day, hour, minute, and second. - /// Its precision is set to [Precision::Second]. + /// Its precision is set to [TimestampPrecision::Second]. pub fn with_ymd_hms( year: u32, month: u32, @@ -538,7 +538,7 @@ impl Timestamp { } /// Creates a TimestampBuilder with the specified year, month, day, hour, minute, second and - /// milliseconds. Its precision is set to [Precision::Second]. + /// milliseconds. Its precision is set to [TimestampPrecision::Second]. pub fn with_ymd_hms_millis( year: u32, month: u32, @@ -562,7 +562,7 @@ impl Timestamp { } /// Returns the precision that has been specified in the [Timestamp]. - pub fn precision(&self) -> Precision { + pub fn precision(&self) -> TimestampPrecision { self.precision } @@ -763,18 +763,18 @@ impl IonEq for Timestamp { if self_dt.year() != other_dt.year() { return false; } - if self.precision >= Precision::Month && self_dt.month() != other_dt.month() { + if self.precision >= TimestampPrecision::Month && self_dt.month() != other_dt.month() { return false; } - if self.precision >= Precision::Day && self_dt.day() != other_dt.day() { + if self.precision >= TimestampPrecision::Day && self_dt.day() != other_dt.day() { return false; } - if self.precision >= Precision::HourAndMinute + if self.precision >= TimestampPrecision::HourAndMinute && (self_dt.hour() != other_dt.hour() || self_dt.minute() != other_dt.minute()) { return false; } - if self.precision <= Precision::HourAndMinute { + if self.precision <= TimestampPrecision::HourAndMinute { return true; } @@ -833,7 +833,7 @@ impl IonOrd for Timestamp { #[derive(Debug, Clone, Default)] struct TimestampBuilder { fields_are_utc: bool, - precision: Precision, + precision: TimestampPrecision, offset: Option, year: u16, month: Option, @@ -848,7 +848,7 @@ struct TimestampBuilder { impl TimestampBuilder { /// Sets all of the fields on the given [`NaiveDateTime`] or [`DateTime`] using the /// values from the TimestampBuilder. Only those fields required by the TimestampBuilder's - /// configured [`Precision`] will be set. + /// configured [`TimestampPrecision`] will be set. fn configure_datetime(&mut self, mut datetime: D) -> IonResult where D: Datelike + Timelike + Debug, @@ -862,7 +862,7 @@ impl TimestampBuilder { datetime = datetime.with_year(self.year as i32).ok_or_else(|| { IonError::illegal_operation(format!("specified year ('{}') is invalid", self.year)) })?; - if self.precision == Precision::Year { + if self.precision == TimestampPrecision::Year { return Ok(datetime); } @@ -871,7 +871,7 @@ impl TimestampBuilder { datetime = datetime.with_month(month as u32).ok_or_else(|| { IonError::illegal_operation(format!("specified month ('{month}') is invalid")) })?; - if self.precision == Precision::Month { + if self.precision == TimestampPrecision::Month { return Ok(datetime); } @@ -880,7 +880,7 @@ impl TimestampBuilder { datetime = datetime.with_day(day as u32).ok_or_else(|| { IonError::illegal_operation(format!("specified day ('{day}') is invalid")) })?; - if self.precision == Precision::Day { + if self.precision == TimestampPrecision::Day { return Ok(datetime); } @@ -893,7 +893,7 @@ impl TimestampBuilder { datetime = datetime.with_minute(minute as u32).ok_or_else(|| { IonError::illegal_operation(format!("specified minute ('{minute}') is invalid")) })?; - if self.precision == Precision::HourAndMinute { + if self.precision == TimestampPrecision::HourAndMinute { return Ok(datetime); } @@ -987,7 +987,7 @@ impl TimestampBuilder { }; // Copy the fractional seconds from the builder to the Timestamp. - if self.precision == Precision::Second { + if self.precision == TimestampPrecision::Second { timestamp.fractional_seconds = self.fractional_seconds; if let Some(Mantissa::Arbitrary(ref decimal)) = ×tamp.fractional_seconds { if decimal.is_less_than_zero() { @@ -1030,7 +1030,7 @@ impl MonthSetter { // 1-indexed month pub fn with_month(self, month: u32) -> DaySetter { let mut builder = self.builder; - builder.precision = Precision::Month; + builder.precision = TimestampPrecision::Month; builder.month = Some(month as u8); DaySetter { builder } } @@ -1061,7 +1061,7 @@ impl DaySetter { // 1-indexed day pub fn with_day(self, day: u32) -> HourAndMinuteSetter { let mut builder = self.builder; - builder.precision = Precision::Day; + builder.precision = TimestampPrecision::Day; builder.day = Some(day as u8); HourAndMinuteSetter { builder } } @@ -1085,13 +1085,13 @@ impl HourAndMinuteSetter { builder.hour = Some(hour as u8); builder.minute = Some(minute as u8); builder.second = Some(second as u8); - builder.precision = Precision::Second; + builder.precision = TimestampPrecision::Second; FractionalSecondSetter { builder } } pub fn with_hour_and_minute(self, hour: u32, minute: u32) -> SecondSetter { let mut builder = self.builder; - builder.precision = Precision::HourAndMinute; + builder.precision = TimestampPrecision::HourAndMinute; builder.hour = Some(hour as u8); builder.minute = Some(minute as u8); SecondSetter { builder } @@ -1114,7 +1114,7 @@ pub struct SecondSetter { impl SecondSetter { pub fn with_second(self, second: u32) -> FractionalSecondSetter { let mut builder = self.builder; - builder.precision = Precision::Second; + builder.precision = TimestampPrecision::Second; builder.second = Some(second as u8); FractionalSecondSetter { builder } } @@ -1233,7 +1233,7 @@ impl_time_unit_setter_for!(SecondSetter); impl_time_unit_setter_for!(FractionalSecondSetter); fn downconvert_to_naive_datetime_with_nanoseconds(timestamp: &Timestamp) -> NaiveDateTime { - if timestamp.precision == Precision::Second { + if timestamp.precision == TimestampPrecision::Second { // DateTime always uses nanosecond precision. If our Timestamp uses a Decimal for // its fractional seconds, attempt to convert it to a number of nanoseconds. // This operation may add or lose precision, but is necessary to conform with @@ -1282,7 +1282,7 @@ impl From for Timestamp { Timestamp { date_time, offset: None, - precision: Precision::Second, + precision: TimestampPrecision::Second, fractional_seconds: Some(Mantissa::Digits(9)), } } @@ -1295,7 +1295,7 @@ impl From> for Timestamp { let date_time = fixed_offset_date_time.naive_utc(); // Get a copy of the offset to store separately let offset = Some(*fixed_offset_date_time.offset()); - let precision = Precision::Second; + let precision = TimestampPrecision::Second; let fractional_seconds = Some(Mantissa::Digits(9)); Timestamp { date_time, @@ -1311,7 +1311,8 @@ mod timestamp_tests { use super::*; use crate::ion_data::IonEq; use crate::result::IonResult; - use crate::types::{Decimal, Mantissa, Precision, Timestamp}; + use crate::types::Mantissa; + use crate::{Decimal, Timestamp, TimestampPrecision}; use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, TimeZone, Timelike}; use rstest::*; use std::cmp::Ordering; @@ -1682,7 +1683,7 @@ mod timestamp_tests { .build_at_offset(-4 * 60) .unwrap_or_else(|e| panic!("Couldn't build timestamp: {e:?}")); - assert_eq!(timestamp1.precision, Precision::Second); + assert_eq!(timestamp1.precision, TimestampPrecision::Second); assert_eq!(timestamp1.fractional_seconds, Some(Mantissa::Digits(3))); assert_eq!(timestamp1, timestamp2); assert_eq!(timestamp2, timestamp3); @@ -1707,7 +1708,7 @@ mod timestamp_tests { #[test] fn test_timestamp_precision() -> IonResult<()> { let timestamp = Timestamp::with_year(2021).with_month(2).build()?; - assert_eq!(timestamp.precision(), Precision::Month); + assert_eq!(timestamp.precision(), TimestampPrecision::Month); Ok(()) } @@ -1885,7 +1886,7 @@ mod timestamp_tests { .build_at_offset(-5 * 60)?; assert_eq!( timestamp_with_redundant_fractional_seconds.precision, - Precision::Second + TimestampPrecision::Second ); assert_eq!( timestamp_with_redundant_fractional_seconds.fractional_seconds_scale(), @@ -1964,13 +1965,13 @@ mod timestamp_tests { let t1 = Timestamp { date_time: NaiveDateTime::from_str("1857-05-29T19:25:59.100").unwrap(), offset: Some(offset_east(60 * 60 * 23 + 60 * 59)), - precision: Precision::Second, + precision: TimestampPrecision::Second, fractional_seconds: Some(Mantissa::Digits(1)), }; let t2 = Timestamp { date_time: NaiveDateTime::from_str("1857-05-29T19:25:59").unwrap(), offset: Some(offset_east(60 * 60 * 23 + 60 * 59)), - precision: Precision::Second, + precision: TimestampPrecision::Second, fractional_seconds: Some(Mantissa::Arbitrary(Decimal::new(1u64, -1))), }; assert_eq!(t1, t2); @@ -1982,13 +1983,13 @@ mod timestamp_tests { let t1 = Timestamp { date_time: NaiveDateTime::from_str("2001-08-01T18:18:49.006").unwrap(), offset: Some(offset_east(60 * 60 + 60)), - precision: Precision::Second, + precision: TimestampPrecision::Second, fractional_seconds: Some(Mantissa::Digits(5)), }; let t2 = Timestamp { date_time: NaiveDateTime::from_str("2001-08-01T18:18:49").unwrap(), offset: Some(offset_east(60 * 60 + 60)), - precision: Precision::Second, + precision: TimestampPrecision::Second, fractional_seconds: Some(Mantissa::Arbitrary(Decimal::new(600u64, -5))), }; assert_eq!(t1, t2); diff --git a/tests/element_test_vectors.rs b/tests/element_test_vectors.rs index c6cd9945..3a20081c 100644 --- a/tests/element_test_vectors.rs +++ b/tests/element_test_vectors.rs @@ -555,8 +555,7 @@ mod non_blocking_native_element_tests { fn make_reader(data: &[u8]) -> IonResult> { // These imports are visible as a temporary workaround. // See: https://github.com/amazon-ion/ion-rust/issues/484 - use ion_rs::binary::constants::v1_0::IVM; - use ion_rs::integration_testing::new_reader; + use ion_rs::integration_testing::{new_reader, IVM}; // If the data is binary, create a non-blocking binary reader. if data.starts_with(&IVM) { let raw_reader = RawBinaryReader::new(data); diff --git a/tests/ion_data_consistency.rs b/tests/ion_data_consistency.rs index aa99935c..d08ec342 100644 --- a/tests/ion_data_consistency.rs +++ b/tests/ion_data_consistency.rs @@ -1,7 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. -use ion_rs::element::{Element, Sequence}; -use ion_rs::IonData; +use ion_rs::{Element, IonData, Sequence}; use std::cmp::Ordering; use std::fmt::Debug; diff --git a/tests/ion_hash_tests.rs b/tests/ion_hash_tests.rs index 2e910364..e7cf36c0 100644 --- a/tests/ion_hash_tests.rs +++ b/tests/ion_hash_tests.rs @@ -3,10 +3,9 @@ use digest::consts::U4096; use digest::{FixedOutput, Reset, Update}; -use ion_rs::element::{Element, Sequence, Struct}; use ion_rs::ion_hash::IonHasher; use ion_rs::result::IonResult; -use ion_rs::types::IntAccess; +use ion_rs::{Element, Sequence, Struct}; use ion_rs::IonError; use std::convert::From;