Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ flate2 = "1.0"
infer = "0.15.0"
# ion-rs version must be pinned because we are using experimental features
# See https://github.com/amazon-ion/ion-cli/issues/155
ion-rs = { version = "1.0.0-rc.11", features = ["experimental", "experimental-ion-hash"] }
ion-rs = { version = "1.0.0-rc.12", features = ["experimental", "experimental-ion-hash", "experimental-tooling-apis"] }
ion-schema = { version = "0.16.0" }
tempfile = "3.2.0"
ion-schema = "0.15.0"
lowcharts = "0.5.8"
serde = { version = "1.0.163", features = ["derive"] }
serde_json = { version = "1.0.81", features = ["arbitrary_precision", "preserve_order"] }
Expand Down
46 changes: 23 additions & 23 deletions src/bin/ion/commands/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::output::CommandOutput;
use anyhow::{bail, Context, Result};
use clap::builder::ValueParser;
use clap::{Arg, ArgAction, ArgMatches, Command};
use ion_rs::v1_0::{EncodedBinaryValue, RawValueRef};
use ion_rs::v1_0::{BinaryValueLiteral, RawValueRef};
use ion_rs::*;
use termcolor::{Color, ColorSpec, WriteColor};

Expand Down Expand Up @@ -265,8 +265,8 @@ impl<'a, 'b> IonInspector<'a, 'b> {
limit_bytes: usize,
hide_expansion: bool,
) -> IonResult<IonInspector<'a, 'b>> {
let text_writer = WriteConfig::<v1_0::Text>::new(TextFormat::Compact)
.build_raw_writer(Vec::with_capacity(TEXT_WRITER_INITIAL_BUFFER_SIZE))?;
let text_writer =
v1_0::RawTextWriter::new(Vec::with_capacity(TEXT_WRITER_INITIAL_BUFFER_SIZE))?;
let inspector = IonInspector {
output: out,
bytes_to_skip,
Expand Down Expand Up @@ -365,11 +365,11 @@ impl<'a, 'b> IonInspector<'a, 'b> {
}

/// If `maybe_item` is:
/// * `Some(entity)`, checks to see if the entity's final byte offset is beyond the configured
/// number of bytes to skip.
/// * `None`, then there is no stream-level entity backing the item (that is: it was the result
/// of a macro expansion). Checks to see if the inspector has already completed its
/// skipping phase on an earlier item.
/// * `Some(entity)`, checks to see if the entity's final byte offset is beyond the configured
/// number of bytes to skip.
/// * `None`, then there is no stream-level entity backing the item (that is: it was the result
/// of a macro expansion). Checks to see if the inspector has already completed its
/// skipping phase on an earlier item.
fn should_skip<T: HasRange>(&mut self, maybe_item: &Option<T>) -> bool {
match maybe_item {
// If this item came from an input literal, see if the input literal ends after
Expand All @@ -382,11 +382,11 @@ impl<'a, 'b> IonInspector<'a, 'b> {
}

/// If `maybe_item` is:
/// * `Some(entity)`, checks to see if the entity's final byte offset is beyond the configured
/// number of bytes to inspect.
/// * `None`, then there is no stream-level entity backing the item. These will always be
/// inspected; if the e-expression that produced the value was not beyond the limit,
/// none of the ephemeral values it produces are either.
/// * `Some(entity)`, checks to see if the entity's final byte offset is beyond the configured
/// number of bytes to inspect.
/// * `None`, then there is no stream-level entity backing the item. These will always be
/// inspected; if the e-expression that produced the value was not beyond the limit,
/// none of the ephemeral values it produces are either.
fn is_past_limit<T: HasRange>(&self, maybe_item: &Option<T>) -> bool {
let limit = self.bytes_to_skip.saturating_add(self.limit_bytes);
maybe_item
Expand Down Expand Up @@ -491,7 +491,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
self.write_comment("End of stream")
}

fn inspect_macro_invocation<'x>(
fn inspect_macro_invocation(
&mut self,
depth: usize,
trailing_delimiter: &str,
Expand All @@ -513,7 +513,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
Ok(())
}

fn inspect_eexp<'x>(
fn inspect_eexp(
&mut self,
depth: usize,
trailing_delimiter: &str,
Expand Down Expand Up @@ -588,7 +588,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
Ok(())
}

fn inspect_eexp_arg_group<'x>(
fn inspect_eexp_arg_group(
&mut self,
depth: usize,
arg_group: EExpArgGroup<AnyEncoding>,
Expand Down Expand Up @@ -955,7 +955,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
&mut self,
depth: usize,
value: LazyValue<'x, AnyEncoding>,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
) -> Result<()> {
if !value.has_annotations() {
return Ok(());
Expand Down Expand Up @@ -1036,7 +1036,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
fn inspect_literal_container_header<'x, D: Decoder>(
&mut self,
depth: usize,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
) -> Result<()> {
let opcode_bytes: &[u8] = encoded_value.value_opcode_span().bytes();
let mut formatter = BytesFormatter::new(
Expand All @@ -1057,7 +1057,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
fn inspect_literal_container_footer<'x, D: Decoder>(
&mut self,
depth: usize,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
closing_delimiter: &str,
trailing_delimiter: &str,
) -> Result<()> {
Expand Down Expand Up @@ -1091,7 +1091,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
depth: usize,
delimiter: &str,
sexp: LazySExp<'x, AnyEncoding>,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
) -> Result<()> {
self.inspect_literal_sequence(
depth,
Expand All @@ -1114,7 +1114,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
closing_delimiter: &str,
trailing_delimiter: &str,
nested_values: impl IntoIterator<Item = IonResult<ValueExpr<'x, AnyEncoding>>>,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
value_comment_fn: impl CommentFn<'x>,
) -> Result<()> {
self.inspect_literal_container_header(depth, encoded_value)?;
Expand Down Expand Up @@ -1305,7 +1305,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
depth: usize,
trailing_delimiter: &str,
struct_: LazyStruct<AnyEncoding>,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
kind: StructKind,
) -> Result<()> {
self.inspect_literal_container_header(depth, encoded_value)?;
Expand Down Expand Up @@ -1421,7 +1421,7 @@ impl<'a, 'b> IonInspector<'a, 'b> {
depth: usize,
delimiter: &str,
value: LazyValue<'x, AnyEncoding>,
encoded_value: impl EncodedBinaryValue<'x, D>,
encoded_value: impl BinaryValueLiteral<'x, D>,
mut comment_fn: impl CommentFn<'x>,
) -> Result<()> {
let range = encoded_value.value_span().range();
Expand Down
30 changes: 18 additions & 12 deletions src/bin/ion/commands/jq.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// The JAQ errors are large and it's out of our control.
#![allow(clippy::result_large_err)]

use crate::commands::jq::ion_math::DecimalMath;
use crate::commands::{CommandIo, IonCliCommand, WithIonCliArgument};
use crate::input::CommandInput;
Expand Down Expand Up @@ -118,10 +121,12 @@ fn filter_and_print(
writer: &mut CommandOutputWriter,
item: JaqElement,
) -> anyhow::Result<()> {
// TODO: See if we can avoid a mutable interior constant here
#[allow(clippy::declare_interior_mutable_const)]
const EMPTY_ITER: RcIter<Empty<Result<JaqElement, String>>> = RcIter::new(core::iter::empty());

let inputs = &EMPTY_ITER; // filter evaluation starts here, no other contextual inputs exist
let ctx = Ctx::new([], inputs); // manages variables etc., use one per filter execution
let inputs = EMPTY_ITER; // filter evaluation starts here, no other contextual inputs exist
let ctx = Ctx::new([], &inputs); // manages variables etc., use one per filter execution
let out = filter.run((ctx, item));

for value in out {
Expand Down Expand Up @@ -207,10 +212,12 @@ impl FromIterator<Self> for JaqElement {

impl PartialEq<Self> for JaqElement {
fn eq(&self, other: &Self) -> bool {
// TODO: Should this use IonData::eq instead?
self.0.eq(&other.0)
}
}

#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for JaqElement {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(IonData::from(self).cmp(&IonData::from(other)))
Expand Down Expand Up @@ -332,9 +339,9 @@ impl Sub for JaqElement {
// Number types, only lossless operations
(Int(a), Int(b)) => (a + -b).into(), //TODO: use bare - with ion-rs > rc.11
(Float(a), Float(b)) => a.sub(b).into(),
(Decimal(a), Decimal(b)) => a.sub(b).into(),
(Decimal(a), Int(b)) => a.sub(b).into(),
(Int(a), Decimal(b)) => a.sub(b).into(),
(Decimal(a), Decimal(b)) => DecimalMath::sub(a, b).into(),
(Decimal(a), Int(b)) => DecimalMath::sub(a, b).into(),
(Int(a), Decimal(b)) => DecimalMath::sub(a, b).into(),

// Only try potentially lossy Float conversions when we've run out of the other options
(a @ Int(_) | a @ Decimal(_), Float(b)) => (a.to_f64().unwrap() - b).into(),
Expand Down Expand Up @@ -564,7 +571,9 @@ impl jaq_core::ValT for JaqElement {
let elt: Element = match (self.value(), index.value()) {
(List(seq) | SExp(seq), Int(i)) => index_i128(seq, i.as_i128()),
(List(seq) | SExp(seq), Float(f)) => index_i128(seq, Some(*f as i128)),
(List(seq) | SExp(seq), Decimal(d)) => index_i128(seq, d.into_big_decimal().to_i128()),
(List(seq) | SExp(seq), Decimal(d)) => {
index_i128(seq, d.clone().into_big_decimal().to_i128())
}
(Struct(strukt), String(name)) => strukt.get(name).or_owned_null(),
(Struct(strukt), Symbol(name)) => strukt.get(name).or_owned_null(),

Expand Down Expand Up @@ -616,10 +625,7 @@ impl jaq_core::ValT for JaqElement {
/// > `if A then B else C end` will act the same as `B` if `A` produces a value other than
/// > `false` or `null`, but act the same as `C` otherwise.
fn as_bool(&self) -> bool {
match self.0.value() {
Value::Null(_) | Value::Bool(false) => false,
_ => true,
}
!matches!(self.0.value(), Value::Null(_) | Value::Bool(false))
}

// If the element is a text value, return its text.
Expand All @@ -642,7 +648,7 @@ impl jaq_std::ValT for JaqElement {
fn as_isize(&self) -> Option<isize> {
match self.0.value() {
Value::Int(i) => i.expect_i64().unwrap().to_isize(),
Value::Decimal(d) => d.into_big_decimal().to_isize(),
Value::Decimal(d) => d.clone().into_big_decimal().to_isize(),
_ => None,
}
}
Expand All @@ -661,7 +667,7 @@ impl jaq_std::ValT for JaqElement {
/// 1. Decimal can express any Int, so any binary operation involving a Decimal and an Int produces
/// a Decimal.
/// 2. Floats have less precision than a Decimal and less range than an Int, so any binary operation
///. involving a Float produces a Float. A Decimal may degrade and lose precision when converted
/// involving a Float produces a Float. A Decimal may degrade and lose precision when converted
/// a Float for arithmetic, but the operation will fail if an operand is out of range for Float.
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.

Thanks :D

pub(crate) mod ion_math {
use bigdecimal::num_bigint::BigInt;
Expand Down
11 changes: 7 additions & 4 deletions src/bin/ion/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ pub trait IonCliCommand {

if !self.is_stable() {
let about = base_command.get_about().map(|x| x.to_string());
if about.is_some() {
base_command = base_command.about(format!("(UNSTABLE) {}", about.unwrap()))
if let Some(about) = about {
base_command = base_command.about(format!("(UNSTABLE) {}", about))
}
base_command = base_command
.before_help("WARNING: This command is unstable and requires explicit opt-in using '--unstable' or '-X'.");
Expand Down Expand Up @@ -240,7 +240,7 @@ pub struct CommandIo<'a> {
}

impl CommandIo<'_> {
fn new(args: &ArgMatches) -> Result<CommandIo> {
fn new(args: &ArgMatches) -> Result<CommandIo<'_>> {
// --format pretty|text|lines|binary
let format = args
.try_get_one("format")
Expand Down Expand Up @@ -375,7 +375,10 @@ impl CommandIo<'_> {
match self.color {
ColorChoice::Never => CommandOutput::StdOut(stdout_lock, spec),
ColorChoice::Auto if !stdout_tty => CommandOutput::StdOut(stdout_lock, spec),
_ => CommandOutput::HighlightedOut(HighlightedStreamWriter::new(stdout_lock), spec),
_ => CommandOutput::HighlightedOut(
Box::new(HighlightedStreamWriter::new(stdout_lock)),
spec,
),
}
};

Expand Down
26 changes: 13 additions & 13 deletions src/bin/ion/commands/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,28 +96,28 @@ impl IonSchemaCommandInput {
// to treat it as an inline type.
type_definition = schema.get_type(type_name_or_inline_type);

if type_definition.is_none() && empty_schema_version.is_some() {
let version = empty_schema_version.unwrap();
// There is no convenient way to add a type to an existing schema, so we'll
// construct a new one.
if type_definition.is_none() {
if let Some(version) = empty_schema_version {
// There is no convenient way to add a type to an existing schema, so we'll
// construct a new one.

// Create a symbol element so that ion-rs handle escaping any special characters.
let type_name = Element::symbol(type_name_or_inline_type);
// Create a symbol element so that ion-rs handle escaping any special characters.
let type_name = Element::symbol(type_name_or_inline_type);

let new_schema = format!(
r#"
let new_schema = format!(
r#"
{version}
type::{{
name: {type_name},
type: {type_name_or_inline_type}
}}
"#
);
// And finally update the schema and type.
schema = schema_system.new_schema(new_schema.as_bytes(), "new-schema")?;
type_definition = schema.get_type(type_name_or_inline_type);
);
// And finally update the schema and type.
schema = schema_system.new_schema(new_schema.as_bytes(), "new-schema")?;
type_definition = schema.get_type(type_name_or_inline_type);
}
}

// Validate that the user didn't pass in an invalid type
type_definition
.as_ref()
Expand Down
2 changes: 1 addition & 1 deletion src/bin/ion/commands/structural_recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub fn visit_structure<V: ValueVisitor<T>, T>(

while let Some((current_value, depth)) = stack.pop() {
let value_ref = current_value.read()?;
visitor.visit(value_ref, depth)?;
visitor.visit(value_ref.clone(), depth)?;

// For container types, add children to the stack with incremented depth
match value_ref {
Expand Down
Loading
Loading