Skip to content

Commit

Permalink
Merge pull request #82 from qubidt/utf8bytelength
Browse files Browse the repository at this point in the history
Implement utf8bytelength function
  • Loading branch information
01mf02 committed Jun 26, 2023
2 parents 00ed64b + 614d8e1 commit 1dad859
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ Here is an overview that summarises:
- [x] Empty (`empty`)
- [x] Errors (`error`)
- [x] Input (`inputs`)
- [x] Length (`length`)
- [x] Length (`length`, `utf8bytelength`)
- [x] Rounding (`floor`, `round`, `ceil`)
- [x] String <-> JSON (`fromjson`, `tojson`)
- [x] String <-> integers (`explode`, `implode`)
Expand Down
3 changes: 3 additions & 0 deletions jaq-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub enum Error {
Arr(Val),
/// `0 == 0 | length`
Length(Val),
/// `0 == 0 | utf8bytelength`
ByteLength(Val),
/// `"a" | round`
Round(Val),
/// `"[1, 2" | fromjson`
Expand Down Expand Up @@ -64,6 +66,7 @@ impl fmt::Display for Error {
Self::Str(v) => write!(f, "cannot use {v} as string"),
Self::Arr(v) => write!(f, "cannot use {v} as array"),
Self::Length(v) => write!(f, "{v} has no length"),
Self::ByteLength(v) => write!(f, "only strings have UTF-8 byte length: {v}"),
Self::Round(v) => write!(f, "cannot round {v}"),
Self::FromJson(v, why) => write!(f, "cannot parse {v} as JSON: {why}"),
Self::Keys(v) => write!(f, "{v} has no keys"),
Expand Down
3 changes: 2 additions & 1 deletion jaq-core/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn box_once<'a, T: 'a>(x: T) -> Box<dyn Iterator<Item = T> + 'a> {
Box::new(core::iter::once(x))
}

const CORE: [(&str, usize, RunPtr); 28] = [
const CORE: [(&str, usize, RunPtr); 29] = [
("inputs", 0, |_, cv| {
Box::new(cv.0.inputs.map(|r| r.map_err(Error::Parse)))
}),
Expand All @@ -93,6 +93,7 @@ const CORE: [(&str, usize, RunPtr); 28] = [
("tojson", 0, |_, cv| {
box_once(Ok(Val::str(cv.1.to_string())))
}),
("utf8bytelength", 0, |_, cv| box_once(cv.1.byte_len())),
("explode", 0, |_, cv| box_once(cv.1.explode().map(Val::arr))),
("implode", 0, |_, cv| box_once(cv.1.implode().map(Val::str))),
("ascii_downcase", 0, |_, cv| {
Expand Down
10 changes: 10 additions & 0 deletions jaq-core/src/val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,16 @@ impl Val {
}
}

/// Return the number of bytes used to encode a string in UTF-8
///
/// Fail on any other value.
pub fn byte_len(&self) -> Result<Self, Error> {
match self {
Self::Str(s) => Ok(Self::Int(s.len() as isize)),
_ => Err(Error::ByteLength(self.clone())),
}
}

/// Apply a rounding function to floating-point numbers, then convert them to integers.
///
/// Return integers unchanged, and fail on any other input.
Expand Down
7 changes: 7 additions & 0 deletions jaq-core/tests/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ fn length() {
give(json!(-2.5), "length", json!(2.5));
}

#[test]
fn utf8bytelength() {
give(json!("foo"), "utf8bytelength", json!(3));
give(json!("ƒoo"), "utf8bytelength", json!(4));
give(json!("नमस्ते"), "utf8bytelength", json!(18));
}

#[test]
fn limit() {
// a big WTF: jq outputs "1" here! that looks like another bug ...
Expand Down

0 comments on commit 1dad859

Please sign in to comment.