Skip to content

Commit

Permalink
Update README and package manifests
Browse files Browse the repository at this point in the history
  • Loading branch information
djkoloski committed Aug 10, 2024
1 parent 2b9a22e commit f55f98e
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 79 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ version = "0.3.0-alpha.3"
authors = ["David Koloski <[email protected]>"]
edition = "2021"
license = "MIT"
documentation = "https://docs.rs/ptr_meta"
readme = "README.md"
repository = "https://github.com/rkyv/ptr_meta"
keywords = ["no_std"]
categories = ["no-std", "no-std::no-alloc"]

[workspace.dependencies]
proc-macro2 = { version = "1.0", default-features = false }
Expand Down
115 changes: 58 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,75 @@
# ptr_meta &emsp; [![Latest Version]][crates.io] [![License]][license path]
# `ptr_meta`

[Latest Version]: https://img.shields.io/crates/v/ptr_meta.svg
[crates.io]: https://crates.io/crates/ptr_meta
[License]: https://img.shields.io/badge/license-MIT-blue.svg
[license path]: https://github.com/djkoloski/ptr_meta/blob/master/LICENSE

A radioactive stabilization of the [`ptr_meta` RFC][rfc].

[rfc]: https://rust-lang.github.io/rfcs/2580-ptr-meta.html

Along with the core `Pointee` trait, `PtrExt` extension trait, and
helper functions, `ptr_meta` also provides inherent implementations for a
common builtin types:

## Sized types

All `Sized` types have `Pointee` implemented for them with a blanket
implementation. You cannot write or derive `Pointee` implementations for these
types.

## `slice`s and `str`s

These core types have implementations provided.

## `CStr` and `OsStr`

These std types have implementations provided when the `std` feature is enabled.
[![crates.io badge]][crates.io] [![docs badge]][docs] [![license badge]][license]

## `dyn Any` (`+ Send`) (`+ Sync`)
[crates.io badge]: https://img.shields.io/crates/v/ptr_meta.svg
[crates.io]: https://crates.io/crates/ptr_meta
[docs badge]: https://img.shields.io/docsrs/ptr_meta
[docs]: https://docs.rs/ptr_meta
[license badge]: https://img.shields.io/badge/license-MIT-blue.svg
[license]: https://github.com/rkyv/ptr_meta/blob/master/LICENSE

`dyn Any`, optionally with `+ Send` and/or `+ Sync`, have implementations
provided.
A radioactive stabilization of the [`ptr_meta` RFC].

## `dyn Error` (`+ Send`) (`+ Sync`)
[`ptr_meta` RFC]: https://rust-lang.github.io/rfcs/2580-ptr-meta.html

`dyn Error`, optionally with `+ Send` and/or `+ Sync`, have implementations
provided when the `std` feature is enabled.
## Documentation

## Structs with trailing DSTs
- [ptr_meta](https://docs.rs/ptr_meta), the core library
- [ptr_meta_derive](https://docs.rs/ptr_meta_derive), proc macros for
implementing `Pointee` for structs and trait objects

You can derive `Pointee` for structs with trailing DSTs:
## Example

```rust
use ptr_meta::Pointee;

#[derive(Pointee)]
struct Block<H, T> {
header: H,
elements: [T],
// Get the associated metadata for pointers
let str = "hello world";
assert_eq!(ptr_meta::metadata(str), str.len());

let slice = &[1, 2, 3, 4, 5] as &[i32];
assert_eq!(ptr_meta::metadata(slice), slice.len());

// Make your own wide pointers from data pointers and metadata
let bytes = [b'h', b'e', b'l', b'l', b'o'];
let ptr = ptr_meta::from_raw_parts::<str>(bytes.as_ptr().cast(), 5);
println!("{} world!", unsafe { &*ptr }); // prints "hello world!"

// Derive Pointee on your own types
#[derive(ptr_meta::Pointee)]
#[repr(transparent)]
struct CoolStr {
inner: str,
}
```

Note that the last field is required to be a DST. Structs with a generic type as
the last field may have conflicting blanket implementations, as the generic type
may be `Sized`. A collection of specific implementations may be required in
these cases, with the generic parameter set (for example) a slice, `str`, or
specific trait object.
impl CoolStr {
fn print_cool(&self) {
println!("😎 {} 😎", &self.inner);
}
}

## Trait objects
let ptr = ptr_meta::from_raw_parts::<CoolStr>(bytes.as_ptr().cast(), 5);
let cool = unsafe { &*ptr };
cool.print_cool(); // prints "😎 hello 😎"

You can generate `Pointee` implementations for trait objects:
// Implement Pointee for trait objects
#[ptr_meta::pointee]
trait Printable {
fn print(&self);
}

```rust
use ptr_meta::pointee;
impl Printable for i32 {
fn print(&self) {
println!("i32: {self}");
}
}

// Generates Pointee for dyn Stringy
#[ptr_meta::pointee]
trait Stringy {
fn as_string(&self) -> String;
let i32_vtable = ptr_meta::metadata(&0i32 as &dyn Printable);
let one_hundred = 100i32;
let printable = ptr_meta::from_raw_parts::<dyn Printable>(
(&one_hundred as *const i32).cast(),
i32_vtable,
);
unsafe {
(*printable).print(); // prints "i32: 100"
}
```

Note that this will not produce implementations for `Trait + Send + Sync`.
5 changes: 3 additions & 2 deletions ptr_meta/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ version.workspace = true
authors.workspace = true
edition.workspace = true
license.workspace = true
readme.workspace = true
repository.workspace = true
keywords.workspace = true
categories.workspace = true
documentation = "https://docs.rs/ptr_meta"
keywords = ["ptr", "meta", "no_std"]
categories = ["no-std"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
52 changes: 52 additions & 0 deletions ptr_meta/examples/readme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
fn main() {
// Get the associated metadata for pointers
let str = "hello world";
assert_eq!(ptr_meta::metadata(str), str.len());

let slice = &[1, 2, 3, 4, 5] as &[i32];
assert_eq!(ptr_meta::metadata(slice), slice.len());

// Make your own wide pointers from data pointers and metadata
let bytes = [b'h', b'e', b'l', b'l', b'o'];
let ptr = ptr_meta::from_raw_parts::<str>(bytes.as_ptr().cast(), 5);
println!("{} world!", unsafe { &*ptr }); // prints "hello world!"

// Derive Pointee on your own types
#[derive(ptr_meta::Pointee)]
#[repr(transparent)]
struct CoolStr {
inner: str,
}

impl CoolStr {
fn print_cool(&self) {
println!("😎 {} 😎", &self.inner);
}
}

let ptr = ptr_meta::from_raw_parts::<CoolStr>(bytes.as_ptr().cast(), 5);
let cool = unsafe { &*ptr };
cool.print_cool(); // prints "😎 hello 😎"

// Implement Pointee for trait objects
#[ptr_meta::pointee]
trait Printable {
fn print(&self);
}

impl Printable for i32 {
fn print(&self) {
println!("i32: {self}");
}
}

let i32_vtable = ptr_meta::metadata(&0i32 as &dyn Printable);
let one_hundred = 100i32;
let printable = ptr_meta::from_raw_parts::<dyn Printable>(
(&one_hundred as *const i32).cast(),
i32_vtable,
);
unsafe {
(*printable).print(); // prints "i32: 100"
}
}
35 changes: 17 additions & 18 deletions ptr_meta/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
//! A radioactive stabilization of the [`ptr_meta` RFC][rfc].
//!
//! `ptr_meta` provides the `Pointee` trait, `from_raw_parts` and `to_raw_parts`
//! functions, and proc macros for deriving `Pointee` for types and implementing
//! `Pointee` for trait objects.
//!
//! [rfc]: https://rust-lang.github.io/rfcs/2580-ptr-meta.html
//!
//! Along with the core [`Pointee`] trait, and helper functions, `ptr_meta` also
//! provides inherent implementations for common types:
//! ## Provided impls
//!
//! `ptr_meta` provides inherent implementations for many builtin types:
//!
//! ## Sized types
//! ### Sized types
//!
//! All [`Sized`] types have [`Pointee`] implemented for them with a blanket
//! implementation. You cannot write or derive [`Pointee`] implementations for
//! these types.
//! All [`Sized`] types implement [`Pointee`] via a blanket implementation. You
//! cannot write or derive [`Pointee`] implementations for these types.
//!
//! ## `slice`s and `str`s
//! ### `slice`s and `str`s
//!
//! These core types have implementations provided.
//!
//! ## `CStr` and `OsStr`
//! ### `CStr` and `OsStr`
//!
//! These std types have implementations provided when the `std` feature is
//! These `std` types have implementations provided when the `std` feature is
//! enabled.
//!
//! ## `dyn Any` (`+ Send`) (`+ Sync`)
//! ### `dyn Any` (`+ Send`) (`+ Sync`)
//!
//! `dyn Any`, optionally with `+ Send` and/or `+ Sync`, have implementations
//! provided.
//!
//! ## `dyn Error` (`+ Send`) (`+ Sync`)
//! ### `dyn Error` (`+ Send`) (`+ Sync`)
//!
//! `dyn Error`, optionally with `+ Send` and/or `+ Sync`, have implementations
//! provided when the `std` feature is enabled.
//!
//! ## Structs with trailing DSTs
//! ### Structs with trailing DSTs
//!
//! You can derive [`Pointee`] for structs with trailing DSTs:
//!
Expand All @@ -50,7 +54,7 @@
//! required in these cases, with the generic parameter set (for example) a
//! slice, `str`, or specific trait object.
//!
//! ## Trait objects
//! ### Trait objects
//!
//! You can generate [`Pointee`] implementations for trait objects:
//!
Expand Down Expand Up @@ -582,8 +586,3 @@ mod derive_tests {
test_pointee(&() as &dyn TestTrait<u32>);
}
}

// Make sure code in readme is tested. This isn't included in the documentation.
#[doc = include_str!("../../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;
5 changes: 4 additions & 1 deletion ptr_meta_derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
[package]
name = "ptr_meta_derive"
description = "Macros for ptr_meta"
description = "Proc macros for ptr_meta"
version.workspace = true
authors.workspace = true
edition.workspace = true
license.workspace = true
readme.workspace = true
repository.workspace = true
keywords.workspace = true
categories.workspace = true
documentation = "https://docs.rs/ptr_meta_derive"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down

0 comments on commit f55f98e

Please sign in to comment.