From a88a6bd02612b85f305aaf87fd80500aa0a97c6b Mon Sep 17 00:00:00 2001 From: Erik Hedvall Date: Mon, 1 Feb 2016 20:13:00 +0100 Subject: [PATCH 1/3] Add SVG/CSS3 color constants --- Cargo.toml | 2 + build/main.rs | 5 ++ build/named.rs | 24 +++++++ build/svg_colors.txt | 147 +++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/named.rs | 14 +++++ 6 files changed, 193 insertions(+) create mode 100644 build/main.rs create mode 100644 build/named.rs create mode 100644 build/svg_colors.txt create mode 100644 src/named.rs diff --git a/Cargo.toml b/Cargo.toml index d7117bf77..8f01a9521 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,8 @@ readme = "README.md" keywords = ["color", "colour", "space", "linear"] license = "MIT OR Apache-2.0" +build = "build/main.rs" + [features] strict = [] diff --git a/build/main.rs b/build/main.rs new file mode 100644 index 000000000..33efabd5c --- /dev/null +++ b/build/main.rs @@ -0,0 +1,5 @@ +mod named; + +fn main() { + named::build(); +} \ No newline at end of file diff --git a/build/named.rs b/build/named.rs new file mode 100644 index 000000000..86f7da276 --- /dev/null +++ b/build/named.rs @@ -0,0 +1,24 @@ +use std::fs::File; +use std::path::Path; +use std::io::{Write, BufRead, BufReader}; + +pub fn build() { + let out_dir = ::std::env::var("OUT_DIR").unwrap(); + let dest_path = Path::new(&out_dir).join("named.rs"); + + let reader = BufReader::new(File::open("build/svg_colors.txt").expect("could not open svg_colors.txt")); + let mut writer = File::create(dest_path).expect("couldn't create named.rs"); + + for line in reader.lines() { + let line = line.unwrap(); + let mut parts = line.split('\t'); + let name = parts.next().expect("couldn't get the color name"); + let mut rgb = parts.next().expect(&format!("couldn't get color for {}", name)).split(", "); + let red: u8 = rgb.next().and_then(|r| r.trim().parse().ok()).expect(&format!("couldn't get red for {}", name)); + let green: u8 = rgb.next().and_then(|r| r.trim().parse().ok()).expect(&format!("couldn't get green for {}", name)); + let blue: u8 = rgb.next().and_then(|r| r.trim().parse().ok()).expect(&format!("couldn't get blue for {}", name)); + + writeln!(writer, "\n///
", name).unwrap(); + writeln!(writer, "pub const {}: (u8, u8, u8) = ({}, {}, {});", name.to_uppercase(), red, green, blue).unwrap(); + } +} \ No newline at end of file diff --git a/build/svg_colors.txt b/build/svg_colors.txt new file mode 100644 index 000000000..30c1ab57c --- /dev/null +++ b/build/svg_colors.txt @@ -0,0 +1,147 @@ +aliceblue 240, 248, 255 +antiquewhite 250, 235, 215 +aqua 0, 255, 255 +aquamarine 127, 255, 212 +azure 240, 255, 255 +beige 245, 245, 220 +bisque 255, 228, 196 +black 0, 0, 0 +blanchedalmond 255, 235, 205 +blue 0, 0, 255 +blueviolet 138, 43, 226 +brown 165, 42, 42 +burlywood 222, 184, 135 +cadetblue 95, 158, 160 +chartreuse 127, 255, 0 +chocolate 210, 105, 30 +coral 255, 127, 80 +cornflowerblue 100, 149, 237 +cornsilk 255, 248, 220 +crimson 220, 20, 60 +cyan 0, 255, 255 +darkblue 0, 0, 139 +darkcyan 0, 139, 139 +darkgoldenrod 184, 134, 11 +darkgray 169, 169, 169 +darkgreen 0, 100, 0 +darkgrey 169, 169, 169 +darkkhaki 189, 183, 107 +darkmagenta 139, 0, 139 +darkolivegreen 85, 107, 47 +darkorange 255, 140, 0 +darkorchid 153, 50, 204 +darkred 139, 0, 0 +darksalmon 233, 150, 122 +darkseagreen 143, 188, 143 +darkslateblue 72, 61, 139 +darkslategray 47, 79, 79 +darkslategrey 47, 79, 79 +darkturquoise 0, 206, 209 +darkviolet 148, 0, 211 +deeppink 255, 20, 147 +deepskyblue 0, 191, 255 +dimgray 105, 105, 105 +dimgrey 105, 105, 105 +dodgerblue 30, 144, 255 +firebrick 178, 34, 34 +floralwhite 255, 250, 240 +forestgreen 34, 139, 34 +fuchsia 255, 0, 255 +gainsboro 220, 220, 220 +ghostwhite 248, 248, 255 +gold 255, 215, 0 +goldenrod 218, 165, 32 +gray 128, 128, 128 +grey 128, 128, 128 +green 0, 128, 0 +greenyellow 173, 255, 47 +honeydew 240, 255, 240 +hotpink 255, 105, 180 +indianred 205, 92, 92 +indigo 75, 0, 130 +ivory 255, 255, 240 +khaki 240, 230, 140 +lavender 230, 230, 250 +lavenderblush 255, 240, 245 +lawngreen 124, 252, 0 +lemonchiffon 255, 250, 205 +lightblue 173, 216, 230 +lightcoral 240, 128, 128 +lightcyan 224, 255, 255 +lightgoldenrodyellow 250, 250, 210 +lightgray 211, 211, 211 +lightgreen 144, 238, 144 +lightgrey 211, 211, 211 +lightpink 255, 182, 193 +lightsalmon 255, 160, 122 +lightseagreen 32, 178, 170 +lightskyblue 135, 206, 250 +lightslategray 119, 136, 153 +lightslategrey 119, 136, 153 +lightsteelblue 176, 196, 222 +lightyellow 255, 255, 224 +lime 0, 255, 0 +limegreen 50, 205, 50 +linen 250, 240, 230 +magenta 255, 0, 255 +maroon 128, 0, 0 +mediumaquamarine 102, 205, 170 +mediumblue 0, 0, 205 +mediumorchid 186, 85, 211 +mediumpurple 147, 112, 219 +mediumseagreen 60, 179, 113 +mediumslateblue 123, 104, 238 +mediumspringgreen 0, 250, 154 +mediumturquoise 72, 209, 204 +mediumvioletred 199, 21, 133 +midnightblue 25, 25, 112 +mintcream 245, 255, 250 +mistyrose 255, 228, 225 +moccasin 255, 228, 181 +navajowhite 255, 222, 173 +navy 0, 0, 128 +oldlace 253, 245, 230 +olive 128, 128, 0 +olivedrab 107, 142, 35 +orange 255, 165, 0 +orangered 255, 69, 0 +orchid 218, 112, 214 +palegoldenrod 238, 232, 170 +palegreen 152, 251, 152 +paleturquoise 175, 238, 238 +palevioletred 219, 112, 147 +papayawhip 255, 239, 213 +peachpuff 255, 218, 185 +peru 205, 133, 63 +pink 255, 192, 203 +plum 221, 160, 221 +powderblue 176, 224, 230 +purple 128, 0, 128 +red 255, 0, 0 +rosybrown 188, 143, 143 +royalblue 65, 105, 225 +saddlebrown 139, 69, 19 +salmon 250, 128, 114 +sandybrown 244, 164, 96 +seagreen 46, 139, 87 +seashell 255, 245, 238 +sienna 160, 82, 45 +silver 192, 192, 192 +skyblue 135, 206, 235 +slateblue 106, 90, 205 +slategray 112, 128, 144 +slategrey 112, 128, 144 +snow 255, 250, 250 +springgreen 0, 255, 127 +steelblue 70, 130, 180 +tan 210, 180, 140 +teal 0, 128, 128 +thistle 216, 191, 216 +tomato 255, 99, 71 +turquoise 64, 224, 208 +violet 238, 130, 238 +wheat 245, 222, 179 +white 255, 255, 255 +whitesmoke 245, 245, 245 +yellow 255, 255, 0 +yellowgreen 154, 205, 50 \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index b42fd9728..8253266e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -275,6 +275,7 @@ macro_rules! assert_ranges { pub mod gradient; pub mod pixel; +pub mod named; mod alpha; mod rgb; diff --git a/src/named.rs b/src/named.rs new file mode 100644 index 000000000..b48411265 --- /dev/null +++ b/src/named.rs @@ -0,0 +1,14 @@ +//!A collection of named color constants. +//! +//!They are taken from the [SVG keyword +//!colors](https://www.w3.org/TR/SVG/types.html#ColorKeywords) (same as in +//!CSS3) and they can be used as if they were pixel values: +//! +//!``` +//!use palette::Rgb; +//!use palette::pixel::Srgb; +//! +//!let color: Rgb = Srgb::from_pixel(&palette::named::OLIVE).into(); +//!``` + +include!(concat!(env!("OUT_DIR"), "/named.rs")); \ No newline at end of file From 57460f85f6b411ddaaac2cf6717e94468f0d1b2e Mon Sep 17 00:00:00 2001 From: Erik Hedvall Date: Tue, 2 Feb 2016 18:06:04 +0100 Subject: [PATCH 2/3] Add named::from_str which maps name strings to colors --- Cargo.toml | 4 ++++ build/main.rs | 2 ++ build/named.rs | 11 +++++++++++ src/lib.rs | 1 + src/named.rs | 19 +++++++++++++++++-- 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8f01a9521..65d2b671a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,12 @@ strict = [] [dependencies] num = "0.1" +phf = "0.7" [dev-dependencies] image = "0.4" approx = "0.1" clap = "1" + +[build-dependencies] +phf_codegen = "0.7" diff --git a/build/main.rs b/build/main.rs index 33efabd5c..a47b7436f 100644 --- a/build/main.rs +++ b/build/main.rs @@ -1,3 +1,5 @@ +extern crate phf_codegen; + mod named; fn main() { diff --git a/build/named.rs b/build/named.rs index 86f7da276..12a77c422 100644 --- a/build/named.rs +++ b/build/named.rs @@ -8,6 +8,7 @@ pub fn build() { let reader = BufReader::new(File::open("build/svg_colors.txt").expect("could not open svg_colors.txt")); let mut writer = File::create(dest_path).expect("couldn't create named.rs"); + let mut entries = vec![]; for line in reader.lines() { let line = line.unwrap(); @@ -20,5 +21,15 @@ pub fn build() { writeln!(writer, "\n///
", name).unwrap(); writeln!(writer, "pub const {}: (u8, u8, u8) = ({}, {}, {});", name.to_uppercase(), red, green, blue).unwrap(); + + entries.push((name.to_owned(), name.to_uppercase())); + } + + write!(writer, "static COLORS: ::phf::Map<&'static str, (u8, u8, u8)> = ").unwrap(); + let mut map = ::phf_codegen::Map::new(); + for &(ref key, ref value) in &entries { + map.entry(&**key, value); } + map.build(&mut writer).unwrap(); + writeln!(writer, ";").unwrap(); } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 8253266e0..ab071f295 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,6 +47,7 @@ #[macro_use] extern crate approx; extern crate num; +extern crate phf; use num::{Float, ToPrimitive, NumCast}; diff --git a/src/named.rs b/src/named.rs index b48411265..406764633 100644 --- a/src/named.rs +++ b/src/named.rs @@ -7,8 +7,23 @@ //!``` //!use palette::Rgb; //!use palette::pixel::Srgb; +//!use palette::named; //! -//!let color: Rgb = Srgb::from_pixel(&palette::named::OLIVE).into(); +//!//From constant +//!let from_const: Rgb = Srgb::from_pixel(&named::OLIVE).into(); +//! +//!//From name string +//!let olive = named::from_str("olive").expect("unknown color"); +//!let from_str: Rgb = Srgb::from_pixel(&olive).into(); +//! +//!assert_eq!(from_const, from_str); //!``` -include!(concat!(env!("OUT_DIR"), "/named.rs")); \ No newline at end of file +include!(concat!(env!("OUT_DIR"), "/named.rs")); + +///Get a SVG/CSS3 color by name. +/// +///The names are the same as the constants, but lower case. +pub fn from_str(name: &str) -> Option<(u8, u8, u8)> { + COLORS.get(name).cloned() +} From a401917f9e545d83f95a0c2dc67452bca08a2bd3 Mon Sep 17 00:00:00 2001 From: Erik Hedvall Date: Tue, 2 Feb 2016 18:52:00 +0100 Subject: [PATCH 3/3] Make the named module and named::from_str optional --- .travis.yml | 1 + Cargo.toml | 15 +++++++++++--- README.md | 7 +++++++ build/main.rs | 1 + build/named.rs | 29 +++++++++++++++++++++----- scripts/test_features.sh | 45 ++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 +++++ src/named.rs | 7 +++++-- 8 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 scripts/test_features.sh diff --git a/.travis.yml b/.travis.yml index 1852299f0..6f6f8be71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ branches: script: - cargo build -v --features strict - cargo test -v --features strict + - bash scripts/test_features.sh - cargo doc after_success: - sh scripts/upload_doc.sh \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 65d2b671a..229d7da58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,16 +13,25 @@ license = "MIT OR Apache-2.0" build = "build/main.rs" [features] +default = ["named_from_str"] +named_from_str = ["named", "phf", "phf_codegen"] +named = [] + +#internal strict = [] [dependencies] num = "0.1" -phf = "0.7" + +[dependencies.phf] +version = "0.7" +optional = true [dev-dependencies] image = "0.4" approx = "0.1" clap = "1" -[build-dependencies] -phf_codegen = "0.7" +[build-dependencies.phf_codegen] +version = "0.7" +optional = true diff --git a/README.md b/README.md index df457ef71..fa5aae182 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,13 @@ Add the following lines to your `Cargo.toml` file: palette = "0.2" ``` +###Optional Features + +These features are enabled by default: + + * `"named"` - Enables color constants, located in the `named` module. + * `"named_from_str"` - Enables the `named::from_str`, which maps name string to colors. + # Linear? Colors in, for example, images are often "gamma corrected" or stored in sRGB diff --git a/build/main.rs b/build/main.rs index a47b7436f..a20ec502c 100644 --- a/build/main.rs +++ b/build/main.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "phf_codegen")] extern crate phf_codegen; mod named; diff --git a/build/named.rs b/build/named.rs index 12a77c422..c19d58ec1 100644 --- a/build/named.rs +++ b/build/named.rs @@ -1,8 +1,10 @@ use std::fs::File; -use std::path::Path; -use std::io::{Write, BufRead, BufReader}; +#[cfg(feature = "named")] pub fn build() { + use std::path::Path; + use std::io::{Write, BufRead, BufReader}; + let out_dir = ::std::env::var("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("named.rs"); @@ -25,11 +27,28 @@ pub fn build() { entries.push((name.to_owned(), name.to_uppercase())); } + gen_from_str(&mut writer, &entries) +} + +#[cfg(feature = "named_from_str")] +fn gen_from_str(writer: &mut File, entries: &[(String, String)]) { + use std::io::Write; + write!(writer, "static COLORS: ::phf::Map<&'static str, (u8, u8, u8)> = ").unwrap(); let mut map = ::phf_codegen::Map::new(); - for &(ref key, ref value) in &entries { + for &(ref key, ref value) in entries { map.entry(&**key, value); } - map.build(&mut writer).unwrap(); + map.build(writer).unwrap(); writeln!(writer, ";").unwrap(); -} \ No newline at end of file +} + + + + +#[cfg(not(feature = "named"))] +pub fn build() {} + +#[allow(unused)] +#[cfg(not(feature = "named_from_str"))] +fn gen_from_str(_writer: &mut File, _entries: &[(String, String)]) {} diff --git a/scripts/test_features.sh b/scripts/test_features.sh new file mode 100644 index 000000000..a1eb0a221 --- /dev/null +++ b/scripts/test_features.sh @@ -0,0 +1,45 @@ +set -e + +#List of features to test +features="" + +#Features that will always be activated +required_features="strict" + + +#Find features +walking_features=false +current_dependency="" + +while read -r line || [[ -n "$line" ]]; do + if [[ "$line" == "[features]" ]]; then + walking_features=true + elif [[ $walking_features == true ]] && [[ "$line" == "#internal" ]]; then + walking_features=false + elif [[ $walking_features == true ]] && echo "$line" | grep -E "^\[.*\]" > /dev/null; then + walking_features=false + elif [[ $walking_features == true ]] && echo "$line" | grep -E ".*=.*" > /dev/null; then + feature="$(echo "$line" | cut -f1 -d"=")" + feature="$(echo -e "${feature}" | tr -d '[[:space:]]')" + if [[ "$feature" != "default" ]]; then + features="$features $feature" + fi + elif echo "$line" | grep -E "^\[dependencies\..*\]" > /dev/null; then + current_dependency="$(echo "$line" | sed 's/.*\[dependencies\.\([^]]*\)\].*/\1/g')" + elif [[ "$line" == "#feature" ]] && [[ "$current_dependency" != "" ]]; then + echo "found dependency feature '$current_dependency'" + features="$features $current_dependency" + fi +done < "Cargo.toml" + +echo -e "features: $features\n" + +#Test without any optional feature +echo compiling with --no-default-features --features "$required_features" +cargo build --no-default-features --features "$required_features" + +#Isolated test of each optional feature +for feature in $features; do + echo compiling with --no-default-features --features "\"$feature $required_features\"" + cargo build --no-default-features --features "$feature $required_features" +done diff --git a/src/lib.rs b/src/lib.rs index ab071f295..9340240c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,10 @@ #[cfg(test)] #[macro_use] extern crate approx; + extern crate num; + +#[cfg(feature = "phf")] extern crate phf; use num::{Float, ToPrimitive, NumCast}; @@ -276,6 +279,8 @@ macro_rules! assert_ranges { pub mod gradient; pub mod pixel; + +#[cfg(feature = "named")] pub mod named; mod alpha; diff --git a/src/named.rs b/src/named.rs index 406764633..87203b43b 100644 --- a/src/named.rs +++ b/src/named.rs @@ -1,4 +1,5 @@ -//!A collection of named color constants. +//!A collection of named color constants. Can be toggled with the `"named"` +//!Cargo feature. //! //!They are taken from the [SVG keyword //!colors](https://www.w3.org/TR/SVG/types.html#ColorKeywords) (same as in @@ -21,9 +22,11 @@ include!(concat!(env!("OUT_DIR"), "/named.rs")); -///Get a SVG/CSS3 color by name. +///Get a SVG/CSS3 color by name. Can be toggled with the `"named_from_str"` +///Cargo feature. /// ///The names are the same as the constants, but lower case. +#[cfg(feature = "named_from_str")] pub fn from_str(name: &str) -> Option<(u8, u8, u8)> { COLORS.get(name).cloned() }