Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an enum_properties_lazy macro that allows arbitrary values. #6

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,19 @@ categories = ["no-std", "rust-patterns"]
[badges]
maintenance = { status = "actively-developed" }

[dependencies.lazy_static]
version = "1.4"
optional = true


[[example]]
name = "basic_usage_lazy"
required-features = ["lazy_static"]

[[example]]
name = "with_all_features_lazy"
required-features = ["lazy_static"]

[[example]]
name = "non_const_lazy"
required-features = ["lazy_static"]
38 changes: 38 additions & 0 deletions examples/basic_usage_lazy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Requires the "lazy_static" feature

use enum_properties::enum_properties_lazy;

pub struct FruitProperties {
pub name: &'static str,
pub description: &'static str,
pub weight: f32,
}

enum_properties_lazy! {
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Fruit: FruitProperties {
Apple {
name: "apple",
description: "Keeps the doctor away.",
weight: 0.1,
},
Orange {
name: "orange",
description: "Round and refreshing.",
weight: 0.13,
},
Banana {
name: "banana",
description: "Elongated and yellow.",
weight: 0.12,
},
}
}

fn main() {
println!("An {} weighs about {} kg.",
Fruit::Apple.name,
Fruit::Apple.weight
);
}
45 changes: 45 additions & 0 deletions examples/non_const_lazy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

use enum_properties::enum_properties_lazy;

/// Custom struct, none-copy, none-clone, not even const-init
pub struct FruitProperties {
pub name: String,
pub features: Vec<f32>,
}

enum_properties_lazy! {
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Fruit: FruitProperties {
Apple {
name: "apple".to_string(),
features: Vec::new(),
},
Orange {
name: {
// Allows arbitrarily complex runtime initializers, thanks
// to the magic of lazy_static
let mut builder = String::new();
builder.push_str("orange");
builder
},
features: {
let mut builder = Vec::new();
builder.push(0.13);
builder.push(0.42);
builder
},
},
Banana {
name: "banana".into(),
features: vec![0.12, 0.34, 0.32],
},
}
}

fn main() {
println!("An {} weighs, {:?}.",
Fruit::Apple.name,
Fruit::Apple.features
);
}
84 changes: 84 additions & 0 deletions examples/with_all_features_lazy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Requires the "lazy_static" feature

use enum_properties::enum_properties_lazy;

pub struct FruitProperties {
pub name: String,
pub description: &'static str,
pub weight: f32,
}

pub const DEFAULT_FRUIT_PROPERTIES: FruitProperties = FruitProperties {
name: String::new(),
description: "Round and refreshing.",
weight: 0.1,
};

enum_properties_lazy! {
// Just like a normal `enum`, an enum defined within an invocation of
// `enum_properties` can have attributes:
#[doc = "Fruit"]
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
pub enum Fruit: FruitProperties {
// Variants can be unit-like, followed only by their static properties:
#[doc = "Fruit::Apple"] // Variants can also have attributes
Apple {
name: "apple".to_string(),
description: "Keeps the doctor away."
},
// Variants can also be tuple-like, containing some non-static data.
// The tuple is defined after the static properties.
#[doc = "Fruit::Orange"]
Orange {
name: "orange".to_string(),
weight: 0.13,
} (
// Members of a tuple-like variant can also have attributes:
#[doc = "Fruit::Orange(segment_count)"]
usize,
),
// Variants can also be struct-like, containing some non-static data.
// The struct is defined after the static properties.
#[doc = "Fruit::Banana"]
Banana {
name: "banana".to_string(),
description: "Elongated and yellow.",
weight: 0.12,
} {
// Members of a struct-like variant can also have attributes:
#[doc = "Fruit::Banana { length }"]
length: f32,
},
// This syntax specifies defaults, such that each variant does not have
// to define all of its static properties. Properties left undefined
// are drawn from this value instead.
.. DEFAULT_FRUIT_PROPERTIES
}
}

fn main() {
let fruits = [
Fruit::Apple,
Fruit::Orange(10),
Fruit::Banana { length: 18.0 },
];

for &fruit in &fruits {
println!("Name: {}", fruit.name);
println!("Weight: {} kg", fruit.weight);
print!("Description: {}", fruit.description);

match fruit {
Fruit::Apple => {
println!(" This one is like all the others.");
}
Fruit::Orange(segment_count) => {
println!(" This one is made of {} segments.", segment_count);
}
Fruit::Banana { length } => {
println!(" This one is {} cm long.", length);
}
}
}
println!("");
}
Loading