Deref
The Deref derive macro implements std::ops::Deref, forwarding to an inner field. This is useful for the newtype pattern — wrapping a type while exposing its methods directly.
Single-Field Structs
For structs with one field, Deref automatically targets that field. No attribute needed.
Tuple Struct
use moxy::Deref;
#[derive(Deref)]
struct Email(String);
let email = Email("john@example.com".into());
assert_eq!(email.len(), 16); // delegates to String::len
Named Struct
use moxy::Deref;
#[derive(Deref)]
struct Email {
raw: String,
}
let email = Email { raw: "john@example.com".into() };
assert_eq!(email.len(), 16);
Multi-Field Structs
When a struct has multiple fields, mark the deref target with #[moxy(deref)]:
use moxy::Deref;
#[derive(Deref)]
struct User {
name: String,
#[moxy(deref)]
email: String,
phone: String,
}
let user = User {
name: "John".into(),
email: "john@example.com".into(),
phone: "".into(),
};
assert_eq!(user.len(), 16); // delegates to email.len()
Warning
Omitting
#[moxy(deref)]on a multi-field struct is a compile error — the macro cannot infer which field to delegate to.
Without #[moxy(deref)] on a multi-field struct, the macro will produce a compile error asking you to specify which field to target.
Use Cases
Note
Derefis intended for the newtype pattern. Delegating to an unrelated field in a multi-field struct can cause surprising behavior for callers who use*or method resolution.
The Deref derive is ideal for the newtype pattern:
use moxy::Deref;
#[derive(Deref)]
struct Username(String);
#[derive(Deref)]
struct Port(u16);
let name = Username("alice".into());
let port = Port(8080);
// Access all String methods on Username
assert!(name.starts_with("ali"));
assert_eq!(name.to_uppercase(), "ALICE");
// Access all u16 methods on Port
assert_eq!(port.leading_zeros(), 3);