refactor(serialization): 重构颜色模块的序列化实现
将手动实现的序列化逻辑替换为派生宏实现 添加foreign_serializer模块处理特殊序列化需求 优化代码结构并减少重复代码
This commit is contained in:
parent
f82575c49b
commit
edc2a0546e
@ -1,10 +1,10 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use palette::{
|
use palette::{
|
||||||
|
FromColor, Hsl, IntoColor, IsWithinBounds, Lab, Oklch, Srgb,
|
||||||
cam16::{Cam16Jch, Parameters},
|
cam16::{Cam16Jch, Parameters},
|
||||||
color_difference::Wcag21RelativeContrast,
|
color_difference::Wcag21RelativeContrast,
|
||||||
convert::FromColorUnclamped,
|
convert::FromColorUnclamped,
|
||||||
FromColor, Hsl, IntoColor, IsWithinBounds, Lab, Oklch, Srgb,
|
|
||||||
};
|
};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -14,6 +14,7 @@ mod color_differ;
|
|||||||
mod color_shifting;
|
mod color_shifting;
|
||||||
mod convert;
|
mod convert;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
mod foreign_serializer;
|
||||||
mod palettes;
|
mod palettes;
|
||||||
mod reversing;
|
mod reversing;
|
||||||
mod schemes;
|
mod schemes;
|
||||||
@ -139,10 +140,6 @@ pub fn wacg_relative_contrast(fg_color: &str, bg_color: &str) -> Result<f32, err
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! cond {
|
macro_rules! cond {
|
||||||
($s: expr, $a: expr, $b: expr) => {
|
($s: expr, $a: expr, $b: expr) => {
|
||||||
if $s {
|
if $s { $a } else { $b }
|
||||||
$a
|
|
||||||
} else {
|
|
||||||
$b
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use internment::Intern;
|
||||||
use material_design_2::MaterialDesign2Scheme;
|
use material_design_2::MaterialDesign2Scheme;
|
||||||
use material_design_3::MaterialDesign3Scheme;
|
use material_design_3::MaterialDesign3Scheme;
|
||||||
use material_design_3_dynamic::{build_baseline, build_dynamic_scheme, build_swatches, Variant};
|
use material_design_3_dynamic::{Variant, build_baseline, build_dynamic_scheme, build_swatches};
|
||||||
use q_style::{QScheme, SchemeSetting};
|
use q_style::{QScheme, SchemeSetting};
|
||||||
use swatch_style::{SwatchEntry, SwatchSchemeSetting};
|
use swatch_style::{SwatchEntry, SwatchSchemeSetting};
|
||||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
|
use wasm_bindgen::{JsValue, prelude::wasm_bindgen};
|
||||||
|
|
||||||
use crate::{errors, schemes::q_style_2::QScheme2};
|
use crate::{errors, schemes::q_style_2::QScheme2};
|
||||||
|
|
||||||
@ -23,6 +24,10 @@ pub trait SchemeExport {
|
|||||||
fn output_javascript_object(&self) -> String;
|
fn output_javascript_object(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_static_str(s: &str) -> &'static str {
|
||||||
|
Intern::new(s.to_string()).as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn generate_material_design_3_scheme(
|
pub fn generate_material_design_3_scheme(
|
||||||
source_color: &str,
|
source_color: &str,
|
||||||
|
@ -5,7 +5,7 @@ use palette::{
|
|||||||
Oklch, ShiftHue,
|
Oklch, ShiftHue,
|
||||||
color_theory::{Analogous, Complementary, SplitComplementary, Tetradic, Triadic},
|
color_theory::{Analogous, Complementary, SplitComplementary, Tetradic, Triadic},
|
||||||
};
|
};
|
||||||
use serde::{Serialize, ser::SerializeStruct};
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
convert::map_oklch_to_srgb_hex,
|
convert::map_oklch_to_srgb_hex,
|
||||||
@ -16,7 +16,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ColorUnit {
|
pub struct ColorUnit {
|
||||||
pub root: ColorSet,
|
pub root: ColorSet,
|
||||||
pub surface: ColorSet,
|
pub surface: ColorSet,
|
||||||
@ -82,20 +83,8 @@ impl ColorUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for ColorUnit {
|
#[derive(Debug, Clone, Serialize)]
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
#[serde(rename_all = "camelCase")]
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
let mut state = serializer.serialize_struct("ColorUnit", 3)?;
|
|
||||||
state.serialize_field("root", &self.root)?;
|
|
||||||
state.serialize_field("surface", &self.surface)?;
|
|
||||||
state.serialize_field("swatch", &self.swatch)?;
|
|
||||||
state.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Baseline {
|
pub struct Baseline {
|
||||||
pub primary: ColorUnit,
|
pub primary: ColorUnit,
|
||||||
pub secondary: Option<ColorUnit>,
|
pub secondary: Option<ColorUnit>,
|
||||||
@ -105,18 +94,26 @@ pub struct Baseline {
|
|||||||
pub neutral_variant: ColorSet,
|
pub neutral_variant: ColorSet,
|
||||||
pub surface: ColorSet,
|
pub surface: ColorSet,
|
||||||
pub surface_variant: ColorSet,
|
pub surface_variant: ColorSet,
|
||||||
|
#[serde(serialize_with = "crate::schemes::q_style_2::swatch::serialize_neutral_swatch")]
|
||||||
pub neutral_swatch: Arc<NeutralSwatch>,
|
pub neutral_swatch: Arc<NeutralSwatch>,
|
||||||
pub danger: ColorUnit,
|
pub danger: ColorUnit,
|
||||||
pub success: ColorUnit,
|
pub success: ColorUnit,
|
||||||
pub warn: ColorUnit,
|
pub warn: ColorUnit,
|
||||||
pub info: ColorUnit,
|
pub info: ColorUnit,
|
||||||
pub custom_colors: HashMap<String, ColorUnit>,
|
pub custom_colors: HashMap<String, ColorUnit>,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub shadow: Oklch,
|
pub shadow: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub overlay: Oklch,
|
pub overlay: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub outline: Oklch,
|
pub outline: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub outline_variant: Oklch,
|
pub outline_variant: Oklch,
|
||||||
|
#[serde(skip)]
|
||||||
pub neutral_lightness: f32,
|
pub neutral_lightness: f32,
|
||||||
|
#[serde(skip)]
|
||||||
pub scheme_settings: Arc<SchemeSetting>,
|
pub scheme_settings: Arc<SchemeSetting>,
|
||||||
|
#[serde(skip)]
|
||||||
pub is_dark: bool,
|
pub is_dark: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,35 +511,3 @@ impl Baseline {
|
|||||||
javascript_fields
|
javascript_fields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for Baseline {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
let mut state = serializer.serialize_struct("Baseline", 17)?;
|
|
||||||
|
|
||||||
state.serialize_field("primary", &self.primary)?;
|
|
||||||
state.serialize_field("secondary", &self.secondary)?;
|
|
||||||
state.serialize_field("tertiary", &self.tertiary)?;
|
|
||||||
state.serialize_field("accent", &self.accent)?;
|
|
||||||
state.serialize_field("neutral", &self.neutral)?;
|
|
||||||
state.serialize_field("neutralVariant", &self.neutral_variant)?;
|
|
||||||
state.serialize_field("surface", &self.surface)?;
|
|
||||||
state.serialize_field("surfaceVariant", &self.surface_variant)?;
|
|
||||||
state.serialize_field("danger", &self.danger)?;
|
|
||||||
state.serialize_field("success", &self.success)?;
|
|
||||||
state.serialize_field("warn", &self.warn)?;
|
|
||||||
state.serialize_field("info", &self.info)?;
|
|
||||||
state.serialize_field("shadow", &map_oklch_to_srgb_hex(&self.shadow))?;
|
|
||||||
state.serialize_field("overlay", &map_oklch_to_srgb_hex(&self.overlay))?;
|
|
||||||
state.serialize_field("outline", &map_oklch_to_srgb_hex(&self.outline))?;
|
|
||||||
state.serialize_field(
|
|
||||||
"outlineVariant",
|
|
||||||
&map_oklch_to_srgb_hex(&self.outline_variant),
|
|
||||||
)?;
|
|
||||||
state.serialize_field("custom", &self.custom_colors)?;
|
|
||||||
|
|
||||||
state.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use palette::{Oklch, color_difference::Wcag21RelativeContrast, luma::Luma};
|
use palette::{Oklch, color_difference::Wcag21RelativeContrast, luma::Luma};
|
||||||
use serde::{Serialize, ser::SerializeStruct};
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
convert::{map_oklch_to_luma, map_oklch_to_srgb_hex},
|
convert::{map_oklch_to_luma, map_oklch_to_srgb_hex},
|
||||||
@ -13,17 +13,28 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ColorSet {
|
pub struct ColorSet {
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub root: Oklch,
|
pub root: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub active: Oklch,
|
pub active: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub focus: Oklch,
|
pub focus: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub hover: Oklch,
|
pub hover: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub disabled: Oklch,
|
pub disabled: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub on_root: Oklch,
|
pub on_root: Oklch,
|
||||||
|
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||||
pub on_disabled: Oklch,
|
pub on_disabled: Oklch,
|
||||||
|
#[serde(skip)]
|
||||||
pub neutral_swatch: Arc<NeutralSwatch>,
|
pub neutral_swatch: Arc<NeutralSwatch>,
|
||||||
|
#[serde(skip)]
|
||||||
pub neutral_lightness: f32,
|
pub neutral_lightness: f32,
|
||||||
|
#[serde(skip)]
|
||||||
pub scheme_settings: Arc<SchemeSetting>,
|
pub scheme_settings: Arc<SchemeSetting>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,28 +277,3 @@ impl ColorSet {
|
|||||||
variables
|
variables
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for ColorSet {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
let root = map_oklch_to_srgb_hex(&self.root);
|
|
||||||
let hover = map_oklch_to_srgb_hex(&self.hover);
|
|
||||||
let active = map_oklch_to_srgb_hex(&self.active);
|
|
||||||
let focus = map_oklch_to_srgb_hex(&self.focus);
|
|
||||||
let disabled = map_oklch_to_srgb_hex(&self.disabled);
|
|
||||||
let on_root = map_oklch_to_srgb_hex(&self.on_root);
|
|
||||||
let on_disabled = map_oklch_to_srgb_hex(&self.on_disabled);
|
|
||||||
|
|
||||||
let mut state = serializer.serialize_struct("ColorSet", 6)?;
|
|
||||||
state.serialize_field("root", &root)?;
|
|
||||||
state.serialize_field("hover", &hover)?;
|
|
||||||
state.serialize_field("active", &active)?;
|
|
||||||
state.serialize_field("focus", &focus)?;
|
|
||||||
state.serialize_field("disabled", &disabled)?;
|
|
||||||
state.serialize_field("onRoot", &on_root)?;
|
|
||||||
state.serialize_field("onDisabled", &on_disabled)?;
|
|
||||||
state.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -6,7 +6,7 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors, parse_option_to_oklch, parse_to_oklch,
|
errors, parse_option_to_oklch, parse_to_oklch,
|
||||||
schemes::{q_style::SchemeSetting, q_style_2::baseline::Baseline, SchemeExport},
|
schemes::{SchemeExport, q_style::SchemeSetting, q_style_2::baseline::Baseline},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod baseline;
|
mod baseline;
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
use internment::Intern;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use palette::Oklch;
|
use palette::Oklch;
|
||||||
use serde::{Serialize, ser::SerializeStruct};
|
use serde::{Serialize, Serializer, ser::SerializeStruct};
|
||||||
|
|
||||||
use crate::convert::map_oklch_to_srgb_hex;
|
use crate::{
|
||||||
|
convert::map_oklch_to_srgb_hex,
|
||||||
|
schemes::{get_static_str, q_style::NeutralSwatch},
|
||||||
|
};
|
||||||
|
|
||||||
static SWATCH_LIGHTINGS: [u8; 16] = [
|
static SWATCH_LIGHTINGS: [u8; 16] = [
|
||||||
10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 75, 80, 85, 90, 95, 98,
|
10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 75, 80, 85, 90, 95, 98,
|
||||||
@ -77,10 +81,6 @@ impl Swatch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_static_str(s: &str) -> &'static str {
|
|
||||||
Intern::new(s.to_string()).as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for Swatch {
|
impl Serialize for Swatch {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
@ -97,3 +97,23 @@ impl Serialize for Swatch {
|
|||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn serialize_neutral_swatch<S>(
|
||||||
|
swatch: &Arc<NeutralSwatch>,
|
||||||
|
serailizer: S,
|
||||||
|
) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let swatch = swatch.clone();
|
||||||
|
let mut swatch_struct = serailizer.serialize_struct("NeutralSwatch", SWATCH_LIGHTINGS.len())?;
|
||||||
|
|
||||||
|
for l in SWATCH_LIGHTINGS {
|
||||||
|
let color = swatch.get((l as f32) / 100.0);
|
||||||
|
let color = map_oklch_to_srgb_hex(&color);
|
||||||
|
let key: &'static str = get_static_str(&format!("{l:02}"));
|
||||||
|
swatch_struct.serialize_field(key, &color)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
swatch_struct.end()
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user