From bd2ce69b7414663de92c94df84dd49b9c37a1ac8 Mon Sep 17 00:00:00 2001 From: jiftechnify Date: Thu, 25 Dec 2025 10:01:39 +0900 Subject: [PATCH 1/3] refine crate level docs --- README.md | 2 +- src/lib.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6c886e7..fcfecb1 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ 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!`. +There is also a `Result`-returning variant of `query_value!`, called `query_value_reosult!`. ### `query_value!` macro A macro for querying, extracting and converting inner value of semi-structured data. diff --git a/src/lib.rs b/src/lib.rs index 9aa4cab..aaa6438 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,23 +1,81 @@ -//! # valq -//! `valq` provides macros for querying and extracting an inner value from a structured data **with the JavaScript-like syntax**. +//! `valq` provides macros for querying semi-structured ("JSON-ish") data **with the JavaScript-like syntax**. //! -//! ``` -//! # use serde_json::json; -//! use serde_json::Value; +//! The principal macro provided by this crate is `query_value!`. Read [the `query_value` doc] for detailed usage. +//! There is also a `Result`-returning variant of `query_value!`, called [`query_value_result!`]. +//! +//! [the `query_value` doc]: crate::query_value +//! [`query_value_result!`]: crate::query_value_result +//! +//! ## Example +//! +//! ```rust +//! use serde_json::{json, Value}; //! use valq::{query_value, query_value_result}; //! -//! // let obj: Value = ...; -//! # let obj = json!({}); -//! let deep_val: Option<&Value> = query_value!(obj.path.to.value.at.deep); -//! let deep_val_res: Result<&Value, valq::Error> = query_value_result!(obj.path.to.value.at.deep); -//! ``` +//! let data = json!({ +//! "package": { +//! "name": "valq", +//! "authors": ["jiftechnify"], +//! "keywords": ["macro", "query", "json"] +//! }, +//! "dependencies": { +//! "paste": { +//! "version": "1.0.15" +//! } +//! }, +//! "dev-dependencies": { +//! "serde": { +//! "version": "1.0.228", +//! "features": ["derive"] +//! } +//! } +//! }); //! -//! The principal macro provided by this crate is `query_value!`. Read [the `query_value` doc] for detailed usage. +//! // simple query +//! assert_eq!( +//! query_value!(data.package.name -> str).unwrap(), +//! "valq" +//! ); //! -//! Also, there is a `Result`-returning variant of `query_value!`, called [`query_value_result!`]. +//! // combining dot-notation & bracket-notation +//! assert_eq!( +//! query_value!(data.package.authors[0] -> str).unwrap(), +//! "jiftechnify" +//! ); //! -//! [the `query_value` doc]: crate::query_value -//! [`query_value_result!`]: crate::query_value_result +//! // deserializing JSON array into Vec +//! assert_eq!( +//! query_value!(data.package.keywords >> (Vec)).unwrap(), +//! ["macro", "query", "json"], +//! ); +//! +//! // Result-returning variant for useful error +//! let res: valq::Result<&str> = query_value_result!(data.package.readme -> str); +//! if let Err(valq::Error::ValueNotFoundAtPath(path)) = res { +//! assert_eq!(path, "data.package.readme"); +//! } else { +//! panic!("should be error"); +//! } +//! +//! // unwrapping with default value +//! assert_eq!( +//! query_value!(data.package.readme -> str ?? "README.md"), +//! "README.md", +//! ); +//! +//! // "dynamic" query with bracket-notation +//! let dep_name = "paste"; +//! assert_eq!( +//! query_value!(data.dependencies[dep_name].version -> str).unwrap(), +//! "1.0.15", +//! ); +//! +//! // put it all together! +//! assert_eq!( +//! query_value!(data["dev-dependencies"].serde.features[0] >> String ?? "none".into()), +//! "derive".to_string(), +//! ); +//! ``` mod error; pub use error::{Error, Result}; From 4ad731b6a31dce81cad1c70f7bf108560ed72436 Mon Sep 17 00:00:00 2001 From: jiftechnify Date: Thu, 25 Dec 2025 10:11:56 +0900 Subject: [PATCH 2/3] fix --- src/lib.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index aaa6438..bdfc028 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ //! ## Example //! //! ```rust +//! use serde::Deserialize; //! use serde_json::{json, Value}; //! use valq::{query_value, query_value_result}; //! @@ -31,19 +32,20 @@ //! } //! }); //! -//! // simple query +//! // Simple query //! assert_eq!( //! query_value!(data.package.name -> str).unwrap(), //! "valq" //! ); //! -//! // combining dot-notation & bracket-notation +//! // Combining dot-notations & bracket-notations //! assert_eq!( //! query_value!(data.package.authors[0] -> str).unwrap(), //! "jiftechnify" //! ); //! -//! // deserializing JSON array into Vec +//! // Deserializing a JSON array into a Vec +//! // Make sure that you put the line: `use serde::Deserialize`! //! assert_eq!( //! query_value!(data.package.keywords >> (Vec)).unwrap(), //! ["macro", "query", "json"], @@ -52,25 +54,25 @@ //! // Result-returning variant for useful error //! let res: valq::Result<&str> = query_value_result!(data.package.readme -> str); //! if let Err(valq::Error::ValueNotFoundAtPath(path)) = res { -//! assert_eq!(path, "data.package.readme"); +//! assert_eq!(path, ".package.readme"); //! } else { //! panic!("should be error"); //! } //! -//! // unwrapping with default value +//! // Unwrapping with default value //! assert_eq!( //! query_value!(data.package.readme -> str ?? "README.md"), //! "README.md", //! ); //! -//! // "dynamic" query with bracket-notation +//! // "Dynamic" query with bracket-notation //! let dep_name = "paste"; //! assert_eq!( //! query_value!(data.dependencies[dep_name].version -> str).unwrap(), //! "1.0.15", //! ); //! -//! // put it all together! +//! // Put it all together! //! assert_eq!( //! query_value!(data["dev-dependencies"].serde.features[0] >> String ?? "none".into()), //! "derive".to_string(), From 6030c641faef61ae9fa809115d9e58327f609314 Mon Sep 17 00:00:00 2001 From: jiftechnify Date: Thu, 25 Dec 2025 10:14:48 +0900 Subject: [PATCH 3/3] add examples directory and put example code from crate-level docs --- examples/basics.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 examples/basics.rs diff --git a/examples/basics.rs b/examples/basics.rs new file mode 100644 index 0000000..2bd9e09 --- /dev/null +++ b/examples/basics.rs @@ -0,0 +1,55 @@ +use serde::Deserialize; +use serde_json::json; +use valq::{query_value, query_value_result}; + +fn main() { + let data = json!({ + "package": { + "name": "valq", + "version": "0.3.0", + "authors": ["jiftechnify"], + "description": "macros for querying semi-structured data with the JavaScript-like syntax", + "keywords": ["macro", "query", "json"] + }, + "dependencies": { + "paste": { "version": "1.0.15" } + }, + "dev-dependencies": { + "serde": { + "version": "1.0.228", + "features": ["derive"] + } + } + }); + + assert_eq!(query_value!(data.package.name -> str).unwrap(), "valq"); + + assert_eq!( + query_value!(data.package.keywords >> (Vec)).unwrap(), + ["macro", "query", "json"], + ); + + let res: valq::Result<&str> = query_value_result!(data.package.readme -> str); + if let Err(valq::Error::ValueNotFoundAtPath(path)) = res { + assert_eq!(path, ".package.readme") + } + else { + unreachable!() + } + + assert_eq!( + query_value!(data.package.readme -> str ?? "README.md"), + "README.md", + ); + + let dep_name = "paste"; + assert_eq!( + query_value!(data.dependencies[dep_name].version -> str).unwrap(), + "1.0.15", + ); + + assert_eq!( + query_value!(data["dev-dependencies"]["serde"].features[0] >> String ?? "none".into()), + "derive".to_string(), + ); +}