diff --git a/Cargo.toml b/Cargo.toml index 5432177..080cdb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "serde_json_path_macros", "serde_json_path_macros/src/internal" ] +resolver = "2" [profile.dev] incremental = false diff --git a/serde_json_path/CHANGELOG.md b/serde_json_path/CHANGELOG.md index 1653826..cd0a98a 100644 --- a/serde_json_path/CHANGELOG.md +++ b/serde_json_path/CHANGELOG.md @@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **documentation**: Add line describing Descendant Operator ([#53]) - **documentation**: Improve example in Filter Selector section of main docs ([#54]) - **documentation**: Improve examples in Slice Slector section of main docs ([#55]) +- **documentation**: Other improvements to documentation ([#56]) [#53]: https://github.com/hiltontj/serde_json_path/pull/53 [#54]: https://github.com/hiltontj/serde_json_path/pull/54 [#55]: https://github.com/hiltontj/serde_json_path/pull/55 +[#55]: https://github.com/hiltontj/serde_json_path/pull/56 # 0.6.2 (13 July 2023) diff --git a/serde_json_path/README.md b/serde_json_path/README.md index 8adf472..8194dbe 100644 --- a/serde_json_path/README.md +++ b/serde_json_path/README.md @@ -26,5 +26,5 @@ additional terms or conditions. [jsonpath]: https://datatracker.ietf.org/wg/jsonpath/about/ [serde_json_value]: https://docs.rs/serde_json/latest/serde_json/enum.Value.html [license]: https://github.com/hiltontj/serde_json_path/blob/main/LICENSE-MIT -[jp_spec]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-14.html +[jp_spec]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html diff --git a/serde_json_path/src/lib.rs b/serde_json_path/src/lib.rs index dbb5306..46ef784 100644 --- a/serde_json_path/src/lib.rs +++ b/serde_json_path/src/lib.rs @@ -1,8 +1,10 @@ //! This crate allows you to use JSONPath queries to extract nodelists from a [`serde_json::Value`]. //! -//! The crate intends to adhere to the [IETF JSONPath specification][jp_spec]. Check out the +//! The crate intends to adhere to the [IETF JSONPath specification][ietf-spec]. Check out the //! specification to read more about JSONPath, and to find many examples of its usage. //! +//! [ietf-spec]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html +//! //! Please note that the specification has not yet been published as an RFC; therefore, this crate //! may evolve as JSONPath becomes standardized. //! @@ -43,8 +45,6 @@ //! //! For queries that are expected to return a single node, use either the //! [`exactly_one`][NodeList::exactly_one] or the [`at_most_one`][NodeList::at_most_one] method. -//! For more lenient single node access, use the [`first`][NodeList::first], -//! [`last`][NodeList::last], or [`get`][NodeList::get] methods. //! //! ```rust //! use serde_json::json; @@ -78,9 +78,11 @@ //! ## Querying for multiple nodes //! //! For queries that are expected to return zero or many nodes, use the [`all`][NodeList::all] -//! method. There are several [selectors][jp_selectors] in JSONPath whose combination can produce +//! method. There are several [selectors][ietf-selectors] in JSONPath whose combination can produce //! useful and powerful queries. //! +//! [ietf-selectors]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-selectors-2 +//! //! #### Wildcards (`*`) //! //! Wildcards select everything under a current node. They work on both arrays, by selecting all @@ -191,10 +193,12 @@ //! //! #### Filter expressions (`?`) //! -//! Filter selectors allow you to perform comparisons and check for existence of nodes. You can -//! combine these checks using the boolean `&&` and `||` operators and group using parentheses. -//! The current node (`@`) operator allows you to apply the filtering logic based on the current -//! node being filtered: +//! [Filter selectors][ietf-filter-selectors] allow you to use logical expressions to evaluate which +//! members in a JSON object or array will be selected. You can use the boolean `&&` and `||` +//! operators as well as parentheses to group logical expressions in your filters. The current node +//! (`@`) operator allows you to utilize the node being filtered in your filter logic: +//! +//! [ietf-filter-selectors]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#name-filter-selector //! //! ```rust //! # use serde_json::json; @@ -253,6 +257,8 @@ //! //! JSONPath query segments following a descendant operator (`..`) will visit the input node and each of its [descendants][ietf-descendants-def]. //! +//! [ietf-descendants-def]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-20.html#section-1.1-6.28.1 +//! //! ```rust //! # use serde_json::json; //! # use serde_json_path::JsonPath; @@ -271,10 +277,6 @@ //! # Ok(()) //! # } //! ``` -//! -//! [jp_spec]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-17.html -//! [jp_selectors]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-17.html#name-selectors-2 -//! [ietf-descendants-def]: https://www.ietf.org/archive/id/draft-ietf-jsonpath-base-17.html#section-1.1-6.28.1 #![warn( clippy::all, diff --git a/serde_json_path_core/src/node.rs b/serde_json_path_core/src/node.rs index f17f629..af1031a 100644 --- a/serde_json_path_core/src/node.rs +++ b/serde_json_path_core/src/node.rs @@ -118,17 +118,57 @@ impl<'a> NodeList<'a> { } /// Returns the first node in the [`NodeList`], or `None` if it is empty + /// + /// # Usage + /// ```rust + /// # use serde_json::json; + /// # use serde_json_path::JsonPath; + /// # fn main() -> Result<(), serde_json_path::ParseError> { + /// let value = json!({"foo": ["bar", "baz"]}); + /// let path = JsonPath::parse("$.foo.*")?; + /// let node = path.query(&value).first(); + /// assert_eq!(node, Some(&json!("bar"))); + /// # Ok(()) + /// # } + /// ``` pub fn first(&self) -> Option<&'a Value> { self.0.first().copied() } /// Returns the last node in the [`NodeList`], or `None` if it is empty + /// + /// # Usage + /// ```rust + /// # use serde_json::json; + /// # use serde_json_path::JsonPath; + /// # fn main() -> Result<(), serde_json_path::ParseError> { + /// let value = json!({"foo": ["bar", "baz"]}); + /// let path = JsonPath::parse("$.foo.*")?; + /// let node = path.query(&value).last(); + /// assert_eq!(node, Some(&json!("baz"))); + /// # Ok(()) + /// # } + /// ``` pub fn last(&self) -> Option<&'a Value> { self.0.last().copied() } /// Returns the node at the given index in the [`NodeList`], or `None` if the given index is /// out of bounds. + /// + /// # Usage + /// ```rust + /// # use serde_json::json; + /// # use serde_json_path::JsonPath; + /// # fn main() -> Result<(), serde_json_path::ParseError> { + /// let value = json!({"foo": ["bar", "biz", "bop"]}); + /// let path = JsonPath::parse("$.foo.*")?; + /// let nodes = path.query(&value); + /// assert_eq!(nodes.get(1), Some(&json!("biz"))); + /// assert!(nodes.get(4).is_none()); + /// # Ok(()) + /// # } + /// ``` pub fn get(&self, index: usize) -> Option<&'a Value> { self.0.get(index).copied() }