refactor(serialization): 重构颜色模块的序列化实现
将手动实现的序列化逻辑替换为派生宏实现 添加foreign_serializer模块处理特殊序列化需求 优化代码结构并减少重复代码
This commit is contained in:
parent
f82575c49b
commit
edc2a0546e
@ -1,10 +1,10 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use palette::{
|
||||
FromColor, Hsl, IntoColor, IsWithinBounds, Lab, Oklch, Srgb,
|
||||
cam16::{Cam16Jch, Parameters},
|
||||
color_difference::Wcag21RelativeContrast,
|
||||
convert::FromColorUnclamped,
|
||||
FromColor, Hsl, IntoColor, IsWithinBounds, Lab, Oklch, Srgb,
|
||||
};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@ -14,6 +14,7 @@ mod color_differ;
|
||||
mod color_shifting;
|
||||
mod convert;
|
||||
mod errors;
|
||||
mod foreign_serializer;
|
||||
mod palettes;
|
||||
mod reversing;
|
||||
mod schemes;
|
||||
@ -139,10 +140,6 @@ pub fn wacg_relative_contrast(fg_color: &str, bg_color: &str) -> Result<f32, err
|
||||
#[macro_export]
|
||||
macro_rules! cond {
|
||||
($s: expr, $a: expr, $b: expr) => {
|
||||
if $s {
|
||||
$a
|
||||
} else {
|
||||
$b
|
||||
}
|
||||
if $s { $a } else { $b }
|
||||
};
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use internment::Intern;
|
||||
use material_design_2::MaterialDesign2Scheme;
|
||||
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 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};
|
||||
|
||||
@ -23,6 +24,10 @@ pub trait SchemeExport {
|
||||
fn output_javascript_object(&self) -> String;
|
||||
}
|
||||
|
||||
pub fn get_static_str(s: &str) -> &'static str {
|
||||
Intern::new(s.to_string()).as_ref()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn generate_material_design_3_scheme(
|
||||
source_color: &str,
|
||||
|
@ -5,7 +5,7 @@ use palette::{
|
||||
Oklch, ShiftHue,
|
||||
color_theory::{Analogous, Complementary, SplitComplementary, Tetradic, Triadic},
|
||||
};
|
||||
use serde::{Serialize, ser::SerializeStruct};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
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 root: ColorSet,
|
||||
pub surface: ColorSet,
|
||||
@ -82,20 +83,8 @@ impl ColorUnit {
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for ColorUnit {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
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)]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Baseline {
|
||||
pub primary: ColorUnit,
|
||||
pub secondary: Option<ColorUnit>,
|
||||
@ -105,18 +94,26 @@ pub struct Baseline {
|
||||
pub neutral_variant: ColorSet,
|
||||
pub surface: ColorSet,
|
||||
pub surface_variant: ColorSet,
|
||||
#[serde(serialize_with = "crate::schemes::q_style_2::swatch::serialize_neutral_swatch")]
|
||||
pub neutral_swatch: Arc<NeutralSwatch>,
|
||||
pub danger: ColorUnit,
|
||||
pub success: ColorUnit,
|
||||
pub warn: ColorUnit,
|
||||
pub info: ColorUnit,
|
||||
pub custom_colors: HashMap<String, ColorUnit>,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub shadow: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub overlay: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub outline: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub outline_variant: Oklch,
|
||||
#[serde(skip)]
|
||||
pub neutral_lightness: f32,
|
||||
#[serde(skip)]
|
||||
pub scheme_settings: Arc<SchemeSetting>,
|
||||
#[serde(skip)]
|
||||
pub is_dark: bool,
|
||||
}
|
||||
|
||||
@ -514,35 +511,3 @@ impl Baseline {
|
||||
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 palette::{Oklch, color_difference::Wcag21RelativeContrast, luma::Luma};
|
||||
use serde::{Serialize, ser::SerializeStruct};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
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 {
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub root: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub active: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub focus: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub hover: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub disabled: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub on_root: Oklch,
|
||||
#[serde(serialize_with = "crate::foreign_serializer::serialize_oklch_to_hex")]
|
||||
pub on_disabled: Oklch,
|
||||
#[serde(skip)]
|
||||
pub neutral_swatch: Arc<NeutralSwatch>,
|
||||
#[serde(skip)]
|
||||
pub neutral_lightness: f32,
|
||||
#[serde(skip)]
|
||||
pub scheme_settings: Arc<SchemeSetting>,
|
||||
}
|
||||
|
||||
@ -266,28 +277,3 @@ impl ColorSet {
|
||||
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::{
|
||||
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;
|
||||
|
@ -1,9 +1,13 @@
|
||||
use internment::Intern;
|
||||
use std::sync::Arc;
|
||||
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
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] = [
|
||||
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 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@ -97,3 +97,23 @@ impl Serialize for Swatch {
|
||||
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