#![cfg_attr(
feature = "unstable-error-generic-member-access",
feature(error_generic_member_access)
)]
#![allow(
unused,
clippy::all,
clippy::pedantic,
reason = "derive-macro test fixtures intentionally trip style lints"
)]
use oopsie::{Oopsie, oopsie};
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(..=128))]
enum SmallError {
#[oopsie("small")]
Small,
}
#[test]
fn size_at_most_passes() {
let _err = SmallError::Small;
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(0..))]
enum AnySize {
#[oopsie("any")]
Any,
}
#[test]
fn size_at_least_passes() {
let _err = AnySize::Any;
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(0))]
enum ZeroSize {
#[oopsie("zero")]
Zero,
}
#[test]
fn size_exact_passes() {
let _err = ZeroSize::Zero;
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(0..=256))]
enum RangeSize {
#[oopsie("range")]
Range,
}
#[test]
fn size_range_passes() {
let _err = RangeSize::Range;
}
#[derive(Debug, Oopsie)]
#[oopsie(size(..=256))]
#[oopsie("struct error: {message}")]
struct StructWithSize {
message: String,
}
#[test]
fn size_struct_passes() {
let _ = std::mem::size_of::<StructWithSize>();
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(24))]
#[oopsie("realistic: {msg}")]
struct RealisticError {
msg: String,
}
#[test]
fn size_exact_realistic_passes() {
assert_eq!(std::mem::size_of::<RealisticError>(), 24);
let _err = RealisticError {
msg: "boom".to_owned(),
};
}
#[derive(Debug, Oopsie)]
#[oopsie(size(..=24))]
#[oopsie("tight: {detail}")]
struct TightUpperBound {
detail: String,
}
#[test]
fn size_at_most_tight_passes() {
assert!(std::mem::size_of::<TightUpperBound>() <= 24);
let _err = TightUpperBound {
detail: "x".to_owned(),
};
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(..=24))]
enum MultiVariantError {
#[oopsie("data: {data}")]
Data { data: String },
#[oopsie("code: {code}")]
Code { code: u32 },
}
#[test]
fn size_multi_variant_enum_passes() {
assert_eq!(std::mem::size_of::<MultiVariantError>(), 24);
let _a = MultiVariantError::Data {
data: "hi".to_owned(),
};
let _b = MultiVariantError::Code { code: 7 };
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(16..))]
enum LowerBoundError {
#[oopsie("payload: {payload}")]
Payload { payload: String },
#[oopsie("empty")]
Empty,
}
#[test]
fn size_at_least_meaningful_passes() {
assert!(std::mem::size_of::<LowerBoundError>() >= 16);
let _err = LowerBoundError::Payload {
payload: "p".to_owned(),
};
let _empty = LowerBoundError::Empty;
}
#[cfg(any())]
struct OnlyWhenEnabled([u8; 9999]);
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(..=8))]
enum CfgGatedError {
#[oopsie("tiny")]
Tiny { byte: u8 },
#[cfg(any())]
#[oopsie("huge")]
Huge { field: OnlyWhenEnabled },
}
#[test]
fn size_cfg_stripped_variant_excluded() {
let _err = CfgGatedError::Tiny { byte: 0 };
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(..25))]
enum BelowError {
#[oopsie("below data: {msg}")]
BelowData { msg: String },
}
#[test]
fn size_below_passes() {
assert_eq!(std::mem::size_of::<BelowError>(), 24);
let _err = BelowError::BelowData {
msg: "x".to_owned(),
};
}
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(24..256))]
enum HalfOpenError {
#[oopsie("half-open data: {msg}")]
HalfOpenData { msg: String },
}
#[test]
fn size_half_open_passes() {
assert_eq!(std::mem::size_of::<HalfOpenError>(), 24);
let _err = HalfOpenError::HalfOpenData {
msg: "x".to_owned(),
};
}
#[cfg(any())]
struct OnlyWhenFieldEnabled([u8; 9999]);
#[oopsie]
#[oopsie(module(false), size(..=8))]
enum CfgGatedFieldError {
#[oopsie("wee")]
Wee {
byte: u8,
#[cfg(any())]
huge: OnlyWhenFieldEnabled,
},
}
#[test]
fn size_cfg_stripped_field_excluded() {
let _err = CfgGatedFieldError::Wee { byte: 0 };
}
#[test]
fn size_check_resolves_fn_local_type() {
#[derive(Debug, Oopsie)]
#[oopsie(module(false), size(..=128))]
enum FnLocalError {
#[oopsie("fn-local: {msg}")]
Local { msg: String },
}
let _err = FnLocalError::Local {
msg: "x".to_owned(),
};
}