Thanks to visit codestin.com
Credit goes to lib.rs

16 releases (breaking)

Uses new Rust 2024

new 0.13.0 May 22, 2026
0.11.0 Mar 29, 2026
0.2.0 Dec 30, 2025

#7 in #json-pointer

Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App

432 downloads per month
Used in 2 crates (via ploidy-pointer)

Apache-2.0

67KB
1.5K SLoC

Derive macros for the JsonPointee and JsonPointerTarget traits.

This crate provides two derive macros:

  • JsonPointee generates an implementation of the JsonPointee trait for traversing structs and enums with JSON Pointer (RFC 6901) syntax. This macro supports Serde-like attributes.
  • JsonPointerTarget generates an implementation of the JsonPointerTarget trait for extracting a reference to the concrete target type from a type-erased pointee.

Container attributes

Container-level attributes apply to structs and enums:

  • #[ploidy(pointer(tag = "field"))] - Use the internally tagged enum representation, with the given field name for the tag. Supported on enums only.
  • #[ploidy(pointer(tag = "t", content = "c"))] - Use the adjacently tagged enum representation, with the given field names for the tag and contents. Supported on enums only.
  • #[ploidy(pointer(untagged))] - Use the untagged enum representation. Supported on enums only.
  • #[ploidy(pointer(rename_all = "case"))] - Rename all struct fields or enum variants according to the given case. The supported cases are lowercase, UPPERCASE, PascalCase, camelCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case, and SCREAMING-KEBAB-CASE.
  • #[ploidy(pointer(crate = "path::to::ploidy_pointer"))] - Override the path to the ploidy_pointer crate. Defaults to ::ploidy_pointer.

Variant Attributes

Variant-level attributes apply to enum variants:

  • #[ploidy(pointer(rename = "name"))] - Access this variant using the given name, instead of its Rust name.
  • #[ploidy(pointer(skip))] - Make this variant inaccessible, except for the tag field if using the internally or adjacently tagged enum representation.

Field Attributes

Field-level attributes apply to struct and enum variant fields:

  • #[ploidy(pointer(rename = "name"))] - Access this variant using the given name, instead of its Rust name.
  • #[ploidy(pointer(flatten))] - Remove one layer of structure between the container and field. Supported on named fields only.
  • #[ploidy(pointer(skip))] - Exclude the field from pointer access.

Examples

Struct flattening

# use ploidy_pointer::{JsonPointerTarget, JsonPointee, JsonPointeeExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(JsonPointee, JsonPointerTarget)]
struct User {
    name: String,
    #[ploidy(pointer(flatten))]
    contact: ContactInfo,
}

#[derive(JsonPointee, JsonPointerTarget)]
struct ContactInfo {
    email: String,
    phone: String,
}

let user = User {
    name: "Alice".to_owned(),
    contact: ContactInfo {
        email: "[email protected]".to_owned(),
        phone: "555-1234".to_owned(),
    },
};
let name: &str = user.pointer("/name")?;
assert_eq!(name, "Alice");
let email: &str = user.pointer("/email")?;
assert_eq!(email, "[email protected]");
let phone: &str = user.pointer("/phone")?;
assert_eq!(phone, "555-1234");
# Ok(())
# }

Renaming fields

# use ploidy_pointer::{JsonPointerTarget, JsonPointee, JsonPointeeExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(JsonPointee, JsonPointerTarget)]
#[ploidy(pointer(rename_all = "snake_case"))]
enum ApiResponse {
    SuccessResponse { data: String },
    #[ploidy(pointer(rename = "error"))]
    ErrorResponse { message: String },
}

let success = ApiResponse::SuccessResponse {
    data: "ok".to_owned(),
};
let data: &str = success.pointer("/success_response/data")?;
assert_eq!(data, "ok");

let error = ApiResponse::ErrorResponse {
    message: "failed".to_owned(),
};
let message: &str = error.pointer("/error/message")?;
assert_eq!(message, "failed");
# Ok(())
# }

Enum representations

Like Serde, #[derive(JsonPointee)] supports externally tagged, internally tagged, adjacently tagged, and untagged enum representations.

Externally tagged

This is the default enum representation. The variant's tag wraps the contents.

# use ploidy_pointer::{JsonPointerTarget, JsonPointee, JsonPointeeExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(JsonPointee, JsonPointerTarget)]
enum Message {
    Text { content: String },
    Image { url: String },
}

let message = Message::Text {
    content: "hello".to_owned(),
};
let content: &str = message.pointer("/Text/content")?;
assert_eq!(content, "hello");
# Ok(())
# }

Internally tagged

In this representation, the tag that specifies the variant name is next to the variant's fields.

# use ploidy_pointer::{JsonPointerTarget, JsonPointee, JsonPointeeExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(JsonPointee, JsonPointerTarget)]
#[ploidy(pointer(tag = "type"))]
enum Message {
    Text { content: String },
    Image { url: String },
}

let message = Message::Text {
    content: "hello".to_owned(),
};
let tag: &str = message.pointer("/type")?;
assert_eq!(tag, "Text");
let content: &str = message.pointer("/content")?;
assert_eq!(content, "hello");
# Ok(())
# }

Adjacently tagged

In this representation, the variant's tag and contents are adjacent to each other, as two fields in the same object.

# use ploidy_pointer::{JsonPointerTarget, JsonPointee, JsonPointeeExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(JsonPointee, JsonPointerTarget)]
#[ploidy(pointer(tag = "type", content = "value"))]
enum Message {
    Text { content: String },
    Image { url: String },
}

let message = Message::Text {
    content: "hello".to_owned(),
};
let tag: &str = message.pointer("/type")?;
assert_eq!(tag, "Text");
let content: &str = message.pointer("/value/content")?;
assert_eq!(content, "hello");
# Ok(())
# }

Untagged

In this representation, the variant's name is completely ignored, and pointers are resolved against the variant's contents.

# use ploidy_pointer::{JsonPointerTarget, JsonPointee, JsonPointeeExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(JsonPointee, JsonPointerTarget)]
#[ploidy(pointer(untagged))]
enum Message {
    Text { content: String },
    Image { url: String },
}

let message = Message::Text {
    content: "hello".to_owned(),
};
let content: &str = message.pointer("/content")?;
assert_eq!(content, "hello");
# Ok(())
# }

ploidy-pointer-derive

This crate provides a derive macro for automatically implementing the JsonPointee trait from the ploidy-pointer crate. For more details about how the macro works, and how to customize the derived implementation, please see the crate docs.

Note: You typically don't need to depend on this crate directly. Instead, please use ploidy-pointer, and enable its derive feature.

Dependencies

~0.5–1MB
~20K SLoC