From ab9e4c1d56df9c8d5f2aef35561f2a84be6fcf68 Mon Sep 17 00:00:00 2001 From: jiftechnify Date: Wed, 17 Dec 2025 23:29:29 +0900 Subject: [PATCH 1/2] update README.md --- README.md | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 32201aa..6c886e7 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [crates.io shield]: https://img.shields.io/crates/v/valq [crates.io link]: https://crates.io/crates/valq -`valq` provides a macro for querying semi-structured ("JSON-ish") data **with the JavaScript-like syntax**. +`valq` provides macros for querying semi-structured ("JSON-ish") data **with the JavaScript-like syntax**. Look & Feel: @@ -34,13 +34,15 @@ Add this to the `Cargo.toml` in your project: valq = "*" ``` +## What's provided + The principal macro provided by this crate is `query_value!`. Also, there is a `Result`-returning variant of `query_value!`, called `query_value_result!`. -## `query_value!` macro +### `query_value!` macro A macro for querying, extracting and converting inner value of semi-structured data. -### Basic Queries +#### Basic Queries ```rust // get field `foo` from JSON object `obj` let foo = query_value!(obj.foo); @@ -52,7 +54,7 @@ let head = query_value!(obj.arr[0]); let abyss = query_value!(obj.path.to.matrix[0][1].abyss); ``` -### Extracting Mutable Reference to Inner Value +#### Extracting Mutable Reference to Inner Value ```rust use serde_json::{json, Value} @@ -67,7 +69,7 @@ assert_eq!(query_value!(obj.foo.bar.x -> u64), Some(100)); assert_eq!(query_value!(obj.foo.bar.y -> u64), Some(200)); ``` -### Casting & Deserializing to Specified Type +#### Casting & Deserializing to Specified Type ```rust // try to cast the queried value into `u64` using `as_u64()` method on that value. // results in `None` in case of type mismatch @@ -94,7 +96,7 @@ let j = json!({"author": {"name": "jiftechnify", "age": 31}}); let author: Option = query_value!(j.author >> (Person)); ``` -### Unwrapping Query Results with Default Values +#### Unwrapping Query Results with Default Values ```rust use serde_json::json; use valq::query_value; @@ -105,7 +107,7 @@ assert_eq!(query_value!(obj.foo.bar -> u64 ?? 42), 42); // explicitly provided d assert_eq!(query_value!(obj.foo.bar -> u64 ?? default), 0u64); // using u64::default() ``` -## `query_value_result!` macro +### `query_value_result!` macro A variant of `query_value!` that returns `Result` instead of `Option`. ```rust @@ -128,6 +130,32 @@ let result = query_value_result!(obj.foo >> (Vec)); assert!(matches!(result, Err(Error::DeserializationFailed(_)))); ``` +### Helper: `transpose_tuple!` macro +Transposes a tuple of `Option`s/`Result`s into an `Option`/`Result` of a tuple. +This is meant to be used with `query_value!`/`query_value_result!` macros, for "cherry-picking" deep value from data. + +```rust +use serde_json::json; +use valq::{query_value, transpose_tuple}; + +let data = json!({"name": "valq", "version": "0.2.0"}); + +// Combine multiple Option results into Option +let picks = transpose_tuple!( + query_value!(data.name -> str), + query_value!(data.version -> str), +); +assert_eq!(picks, Some(("valq", "0.2.0"))); + +// For Result variant, "Result;" prefix is needed +let picks = transpose_tuple!( + Result; + query_value_result!(data.name -> str), + query_value_result!(data.version -> str), +); +assert!(picks.is_ok()); +``` + ## Compatibility The `query_value!` macro can be used with arbitrary data structure(to call, `Value`) that supports `get(&self, idx) -> Option<&Value>` method that retrieves a value at `idx`. From 5d26177d387fcfcbb1416159485fc9a819dc2219 Mon Sep 17 00:00:00 2001 From: jiftechnify Date: Wed, 17 Dec 2025 23:35:56 +0900 Subject: [PATCH 2/2] 0.3.0 --- CHANGELOG.md | 15 +++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 211d729..243ad1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2025-12-17 + +### Added + +- **`query_value_result!` macro** for Result-returning queries ([#56](https://github.com/jiftechnify/valq/pull/56)) + - A new flavor of `query_value!` that returns a `valq::Result` instead of an `Option` + - Enables better error handling for queries where keys or indices might not exist + - Supports all the same query syntax as `query_value!` + +- **`transpose_tuple!` helper macro** for transposing tuples of Results/Options ([#58](https://github.com/jiftechnify/valq/pull/58)) + - Convert `(Option, Option, ...)` into `Option<(A, B, ...)>` + - Convert `(Result, Result, ...)` into `Result<(A, B, ...)>` + - Particularly useful when combining multiple `query_value!`/`query_value_result!` calls + ## [0.2.0] - 2025-12-12 ### Added @@ -48,5 +62,6 @@ Initial release with basic query functionality. - Mutable reference extraction with `mut` prefix - Basic type casting using `as_***()` methods with `->` operator +[0.3.0]: https://github.com/jiftechnify/valq/compare/0.2.0...0.3.0 [0.2.0]: https://github.com/jiftechnify/valq/compare/0.1.0...0.2.0 [0.1.0]: https://github.com/jiftechnify/valq/releases/tag/0.1.0 diff --git a/Cargo.lock b/Cargo.lock index 9af9fed..00d0b20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "valq" -version = "0.2.0" +version = "0.3.0" dependencies = [ "paste", "serde", diff --git a/Cargo.toml b/Cargo.toml index 3e58aa1..10776af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "valq" -version = "0.2.0" +version = "0.3.0" authors = ["jiftechnify "] edition = "2021" license = "MIT"