Skip to content

Commit

Permalink
Merge 584ffae into 3c4a9bb
Browse files Browse the repository at this point in the history
  • Loading branch information
Ogeon authored Apr 9, 2023
2 parents 3c4a9bb + 584ffae commit fbcebf4
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 165 deletions.
6 changes: 3 additions & 3 deletions palette/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ serde_json = "1"
enterpolation = "0.2.0"

[dev-dependencies.clap]
version = "2"
version = "3.2.23"
default-features = false

[dev-dependencies.criterion]
version = "0.3"
version = "0.4.0"
default-features = false

[dev-dependencies.image]
version = "0.23"
version = "0.23.14"
default-features = false
features = ["png"]

Expand Down
97 changes: 41 additions & 56 deletions palette/examples/color_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,126 +2,110 @@ use palette::{Darken, IntoColor, Lch, Lighten, LinSrgb, ShiftHue, Srgb};

use image::{GenericImage, GenericImageView, RgbImage, SubImage};

use clap::{App, AppSettings, Arg, SubCommand};
use clap::{Arg, Command};

const SWATCH_SIZE: u32 = 128;

fn main() {
let matches = App::new("color_scheme")
let matches = Command::new("color_scheme")
.about("Generates a very simple color scheme from an RGB8 color.")
.setting(AppSettings::ArgRequiredElseHelp)
.arg_required_else_help(true)
.arg(
Arg::with_name("red")
Arg::new("red")
.required(true)
.empty_values(false)
.value_parser(clap::value_parser!(u8))
.index(1)
.help("[0-255] The red channel of the primary color."),
)
.arg(
Arg::with_name("green")
Arg::new("green")
.required(true)
.empty_values(false)
.value_parser(clap::value_parser!(u8))
.index(2)
.help("[0-255] The green channel of the primary color."),
)
.arg(
Arg::with_name("blue")
Arg::new("blue")
.required(true)
.empty_values(false)
.value_parser(clap::value_parser!(u8))
.index(3)
.help("[0-255] The blue channel of the primary color."),
)
.subcommand(
SubCommand::with_name("triad")
Command::new("triad")
.about("A three point scheme, centered around the complementary.")
.arg(
Arg::with_name("distance")
Arg::new("distance")
.help("The distance between the secondary colors.")
.long("distance")
.short("d")
.short('d')
.value_name("degrees")
.takes_value(true)
.empty_values(false),
.value_parser(clap::value_parser!(f32)),
),
)
.subcommand(
SubCommand::with_name("analogous")
Command::new("analogous")
.about("Like triad, but centered around the primary.")
.arg(
Arg::with_name("distance")
Arg::new("distance")
.help("The distance between the secondary colors.")
.long("distance")
.short("d")
.short('d')
.value_name("degrees")
.takes_value(true)
.empty_values(false),
.value_parser(clap::value_parser!(f32)),
),
)
.subcommand(
SubCommand::with_name("rectangle")
.about("A four point scheme.")
.arg(
Arg::with_name("distance")
.help("The distance to the closest secondary colors.")
.long("distance")
.short("d")
.value_name("degrees")
.takes_value(true)
.empty_values(false),
),
)
.subcommand(
SubCommand::with_name("complementary").about("A simple two point color scheme."),
Command::new("rectangle").about("A four point scheme.").arg(
Arg::new("distance")
.help("The distance to the closest secondary colors.")
.long("distance")
.short('d')
.value_name("degrees")
.value_parser(clap::value_parser!(f32)),
),
)
.subcommand(Command::new("complementary").about("A simple two point color scheme."))
.get_matches();

//Get the components of the primary color
let red: u8 = matches
.value_of("red")
.and_then(|r| r.parse().ok())
.get_one::<u8>("red")
.copied()
.expect("the red channel must be a number in the range [0-255]");
let green: u8 = matches
.value_of("green")
.and_then(|r| r.parse().ok())
.get_one::<u8>("green")
.copied()
.expect("the green channel must be a number in the range [0-255]");
let blue: u8 = matches
.value_of("blue")
.and_then(|r| r.parse().ok())
.get_one::<u8>("blue")
.copied()
.expect("the blue channel must be a number in the range [0-255]");

let primary: Lch = Srgb::new(red, green, blue).into_linear().into_color();

//Generate the secondary colors, depending on the input arguments
let secondary = match matches.subcommand() {
("triad", matches) | ("", matches) => {
Some(("triad", matches)) | Some(("", matches)) => {
//Two secondary colors that are close to the complementary, or evenly spaced
let distance: f32 = matches
.and_then(|m| m.value_of("distance"))
.and_then(|d| d.parse().ok())
.unwrap_or(120.0);
let distance = matches.get_one::<f32>("distance").copied().unwrap_or(120.0);

let shift = 180.0 - (distance / 2.0);

vec![primary.shift_hue(shift), primary.shift_hue(-shift)]
}
("analogous", matches) => {
Some(("analogous", matches)) => {
//Two secondary colors that are close to the primary
let distance: f32 = matches
.and_then(|m| m.value_of("distance"))
.and_then(|d| d.parse().ok())
.unwrap_or(60.0);
let distance = matches.get_one::<f32>("distance").copied().unwrap_or(60.0);

let shift = distance / 2.0;

vec![primary.shift_hue(shift), primary.shift_hue(-shift)]
}
("rectangle", matches) => {
Some(("rectangle", matches)) => {
//Three secondary colors that forms a rectangle or a square, together with the
// primary
let distance: f32 = matches
.and_then(|m| m.value_of("distance"))
.and_then(|d| d.parse().ok())
.unwrap_or(90.0);
let distance = matches.get_one::<f32>("distance").copied().unwrap_or(90.0);

let shift1 = distance;
let shift2 = 180.0 + distance;
Expand All @@ -132,8 +116,9 @@ fn main() {
primary.shift_hue(shift2),
]
}
("complementary", _) => vec![primary.shift_hue(180.0)], // Simply the complementary color
(name, _) => panic!("unknown subcommand: {}", name),
Some(("complementary", _)) => vec![primary.shift_hue(180.0)], // Simply the complementary color
Some((name, _)) => panic!("unknown subcommand: {}", name),
None => panic!("expected a subcommand"),
};

//Create an image for the swatches
Expand Down
4 changes: 2 additions & 2 deletions palette_derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "palette_derive"
version = "0.6.1" #automatically updated
version = "0.6.1" #automatically updated
authors = ["Erik Hedvall <hello@erikhedvall.nu>"]
exclude = []
description = "Automatically implement traits from the palette crate."
Expand All @@ -17,7 +17,7 @@ proc-macro = true
bench = false

[dependencies]
syn = { version = "^1.0", default-features = false, features = [
syn = { version = "2.0.13", default-features = false, features = [
"derive",
"parsing",
"printing",
Expand Down
26 changes: 20 additions & 6 deletions palette_derive/src/cast/array_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use proc_macro::TokenStream;
use proc_macro2::Span;

use quote::{quote, ToTokens};
use syn::{Attribute, Data, DeriveInput, Fields, Ident, Type};
use syn::{
punctuated::Punctuated, token::Comma, Attribute, Data, DeriveInput, Fields, Meta, Path, Type,
};

use crate::meta::{self, FieldAttributes, IdentOrIndex, TypeItemAttributes};
use crate::util;
Expand Down Expand Up @@ -125,20 +127,32 @@ fn is_allowed_repr(attributes: &[Attribute]) -> std::result::Result<bool, Vec<sy
let mut errors = Vec::new();

for attribute in attributes {
let attribute_name = attribute.path.get_ident().map(ToString::to_string);
let attribute_name = attribute.path().get_ident().map(ToString::to_string);

if let Some("repr") = attribute_name.as_deref() {
let items = match meta::parse_tuple_attribute(attribute.tokens.clone()) {
let meta_list = match attribute.meta.require_list() {
Ok(list) => list,
Err(error) => {
errors.push(error);
continue;
}
};

let items = match meta_list.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)
{
Ok(items) => items,
Err(error) => {
errors.push(error);
continue;
}
};

let contains_allowed_repr = items
.iter()
.any(|item: &Ident| item == "C" || item == "transparent");
let contains_allowed_repr = items.iter().any(|item| {
item.require_path_only()
.ok()
.and_then(Path::get_ident)
.map_or(false, |ident| ident == "C" || ident == "transparent")
});

if contains_allowed_repr {
return Ok(true);
Expand Down
8 changes: 6 additions & 2 deletions palette_derive/src/meta/field_attributes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet};

use syn::spanned::Spanned;
use syn::{spanned::Spanned, Expr, ExprLit};
use syn::{Lit, Meta, MetaNameValue, Result, Type};

use super::{assert_path_meta, FieldAttributeArgumentParser, IdentOrIndex};
Expand All @@ -23,7 +23,11 @@ impl FieldAttributeArgumentParser for FieldAttributes {
}
Some("unsafe_same_layout_as") => {
let substitute = if let Meta::NameValue(MetaNameValue {
lit: Lit::Str(string),
value:
Expr::Lit(ExprLit {
lit: Lit::Str(string),
..
}),
..
}) = argument
{
Expand Down
Loading

0 comments on commit fbcebf4

Please sign in to comment.