dot-prop 0.1.0

Get, set, has, and delete a property from a nested JSON value using a dot path (a.b.0.c). A faithful port of the dot-prop npm package.
Documentation
# dot-prop

[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)

[![crates.io](https://img.shields.io/crates/v/dot-prop.svg)](https://crates.io/crates/dot-prop)
[![docs.rs](https://docs.rs/dot-prop/badge.svg)](https://docs.rs/dot-prop)
[![CI](https://github.com/trananhtung/dot-prop/actions/workflows/ci.yml/badge.svg)](https://github.com/trananhtung/dot-prop/actions/workflows/ci.yml)
[![license](https://img.shields.io/crates/l/dot-prop.svg)](#license)

**Get, set, check, and delete nested JSON values by dot path.**

`get_property(&value, "foo.bar.0")`, `set_property(&mut value, "a[1].b", json!(2))`. A
faithful Rust port of the widely-used
[`dot-prop`](https://www.npmjs.com/package/dot-prop) npm package, operating on
[`serde_json::Value`].

Unlike [`json-pointer`](https://crates.io/crates/json-pointer) (RFC 6901, `/`-separated),
this uses the JavaScript `dot-prop` dot-path syntax: `.` separates keys, `[i]` indexes
arrays, and `\` escapes a literal `.`, `[`, or `\`.

- `get_property`, `set_property`, `has_property`, `delete_property`
- `parse_path` / `stringify_path` / `escape_path`, plus `deep_keys` and `unflatten`
- Prototype-pollution guard (`__proto__`, `prototype`, `constructor` are rejected)
- Differential-tested against the reference `dot-prop` implementation (60k cases across all
  operations)

## Install

```toml
[dependencies]
dot-prop = "0.1"
serde_json = "1"
```

## Usage

```rust
use serde_json::json;
use dot_prop::{get_property, set_property, has_property, delete_property, deep_keys, unflatten};

let mut value = json!({ "foo": { "bar": [10, 20] } });

assert_eq!(get_property(&value, "foo.bar.1"), Some(&json!(20)));
assert_eq!(get_property(&value, "foo.bar[0]"), Some(&json!(10)));
assert!(has_property(&value, "foo.bar.0"));

set_property(&mut value, "foo.bar.2", json!(30));
assert_eq!(get_property(&value, "foo.bar.2"), Some(&json!(30)));

delete_property(&mut value, "foo.bar.0"); // leaves a null hole, like JS `delete`
assert_eq!(get_property(&value, "foo.bar.0"), Some(&json!(null)));

// Flatten/expand helpers:
assert_eq!(deep_keys(&json!({ "a": { "b": 1 } })), ["a.b"]);
assert_eq!(unflatten(&json!({ "a.b": 1 })), json!({ "a": { "b": 1 } }));
```

## Notes

- `get_property` returns the value itself when the input is not an object/array (matching the
  reference's default-value behavior).
- This crate sets the correct keys and values; the *serialization order* of object keys is
  governed by `serde_json` (enable its `preserve_order` feature for insertion order). The
  JavaScript original reorders integer-like keys first — a runtime quirk that does not apply
  to Rust.

## Contributors ✨

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome — code, docs, bug reports, ideas, reviews! See the [emoji key](https://allcontributors.org/docs/en/emoji-key) for how each contribution is recognized, and open a PR or issue to get involved.

Thanks goes to these wonderful people:

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tbody>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/trananhtung"><img src="https://avatars.githubusercontent.com/u/30992229?v=4?s=100" width="100px;" alt="Tung Tran"/><br /><sub><b>Tung Tran</b></sub></a><br /><a href="https://github.com/trananhtung/./commits?author=trananhtung" title="Code">💻</a> <a href="#maintenance-trananhtung" title="Maintenance">🚧</a></td>
    </tr>
  </tbody>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

## License

Licensed under either of [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE) at your option.