#reflection #fields #public #non #type #function #attr

macro pastiche

A library for exposing non public types, fields, and functions from a crate

1 unstable release

0.2.0 Nov 19, 2024
0.1.0 Nov 13, 2024

#386 in Procedural macros

Download history 108/week @ 2024-11-11 167/week @ 2024-11-18 2/week @ 2024-11-25 3/week @ 2024-12-02 7/week @ 2024-12-09

187 downloads per month

MIT/Apache

31KB
546 lines

A library for exposing non public types, fields, and functions from a crate.

The libraries I use often expose most of their lower level details but forget to mark a few structs or fields as public. Necessitating me to copy over the struct, a load of traits, all the methods I need, everything those traits and methods need to import, and all the crates they use. Just for me to be able to add "pub" in front of it.

Most functionality is implemented but this is mainly meant for testing or debugging and is still a work in progress. So don't use this for production code.

Features and Roadmap

  • copy definition
  • change visibility
  • most items: const, enum, fn, macro_rules, static, struct, trait, union
  • attributes
  • std library crates
  • [ ] support not specifying crate verion/dont use file system paths
    • support not specifying rustc version
  • copying modules
  • re-exports
  • recursivly copying item dependancies
  • "safe"-ish transmutes

Ideas

  • enforcing, changing, adding, removing, ignoring:
    • items variant (Struct, fn, etc)
    • field names
    • field types
    • field size, alignment
    • associated types and constants
    • method arguments
    • method return value

Example

use pastiche::pastiche_attr;
use std::num::IntErrorKind;
use std::str::FromStr;

/// A new type that shadows the definition and attributes at
/// [`core::num::ParseIntError`].
/// Internally it searches the fs and copy-pastes the definition.
#[pastiche_attr]
#[pastiche_crate = "stable@1.82.0"]
// NOTE: doesn't support re-exports rn, so we have to specify the
// "real" module path
#[pastiche_path = "core::num::error::ParseIntError"]
#[pastiche_sub_vis(pub)] // set fields to public
pub struct MyParseIntError {
    // body is ignored for now
}

fn main() {
    // We can now directly construct a ParseIntError.
    let my_error = MyParseIntError { kind: IntErrorKind::InvalidDigit };
    dbg!(&my_error);

    // Rather than having to fail a parse. :/
    let std_error = i32::from_str("baddbeef").unwrap_err();
    dbg!(&std_error);

    assert_eq!(&my_error.kind, std_error.kind());
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~0.2–6.5MB
~48K SLoC