diff --git a/Cargo.toml b/Cargo.toml
index 2ca8bdc..cbd514c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,8 @@ members = [
"crates/app",
"crates/eval",
"crates/ir",
- "crates/lang", "crates/svg-filters",
+ "crates/lang",
+ "crates/svg-filters",
]
resolver = "2"
diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml
index 2caaaf4..10182c2 100644
--- a/crates/app/Cargo.toml
+++ b/crates/app/Cargo.toml
@@ -2,6 +2,7 @@
name = "app"
version = "0.1.0"
edition = "2021"
+default-run = "app"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/crates/svg-filters/src/lib.rs b/crates/svg-filters/src/lib.rs
index 11b6708..5081a19 100644
--- a/crates/svg-filters/src/lib.rs
+++ b/crates/svg-filters/src/lib.rs
@@ -1,16 +1,5 @@
-pub fn add(left: usize, right: usize) -> usize {
- left + right
-}
-
pub mod types;
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn it_works() {
- let result = add(2, 2);
- assert_eq!(result, 4);
- }
-}
+pub use types::nodes::Node;
+pub use types::Edge;
+pub use types::Filter;
diff --git a/crates/svg-filters/src/main.rs b/crates/svg-filters/src/main.rs
new file mode 100644
index 0000000..d628d3e
--- /dev/null
+++ b/crates/svg-filters/src/main.rs
@@ -0,0 +1,54 @@
+use svg_filters::{types::nodes::primitives::color_matrix::ColorMatrixType, Edge, Filter, Node};
+
+fn main() {
+ let mut filter = Filter::new();
+
+ //
+ //
+ //
+ //
+
+ //
+
+ //
+ //
+ //
+
+ //
+ //
+ //
+
+ let chan_r = filter.add_node(Node::color_matrix(ColorMatrixType::Matrix(Box::new([
+ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
+ ]))));
+ let chan_g = filter.add_node(Node::color_matrix(ColorMatrixType::Matrix(Box::new([
+ 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
+ ]))));
+ let chan_b = filter.add_node(Node::color_matrix(ColorMatrixType::Matrix(Box::new([
+ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0.,
+ ]))));
+
+ let offset_r = filter.add_node(Node::offset(25., 0.));
+ let offset_b = filter.add_node(Node::offset(-25., 0.));
+ let blur_r = filter.add_node(Node::gaussian_blur_xy(5, 0));
+ let blur_b = filter.add_node(Node::gaussian_blur_xy(5, 0));
+
+ let composite_rb = filter.add_node(Node::composite_arithmetic(0., 1., 1., 0.));
+ let composite_final = filter.add_node(Node::composite_arithmetic(0., 1., 1., 0.));
+
+ filter.graph.extend_with_edges(&[
+ (filter.source_graphic(), chan_r, Edge::new()),
+ (filter.source_graphic(), chan_b, Edge::new()),
+ (filter.source_graphic(), chan_g, Edge::new()),
+ (chan_r, offset_r, Edge::new()),
+ (offset_r, blur_r, Edge::new()),
+ (chan_b, offset_b, Edge::new()),
+ (offset_b, blur_b, Edge::new()),
+ (blur_r, composite_rb, Edge::in_idx(0)),
+ (blur_b, composite_rb, Edge::in_idx(1)),
+ (composite_rb, composite_final, Edge::in_idx(0)),
+ (chan_g, composite_final, Edge::in_idx(1)),
+ ]);
+
+ println!("{filter:#?}")
+}
diff --git a/crates/svg-filters/src/types.rs b/crates/svg-filters/src/types.rs
index 94ecb4b..31e0954 100644
--- a/crates/svg-filters/src/types.rs
+++ b/crates/svg-filters/src/types.rs
@@ -1,20 +1,80 @@
use std::collections::HashMap;
-use petgraph::graphmap::DiGraphMap;
+use petgraph::{
+ adj::EdgeIndex, data::Build, graph::DiGraph, graphmap::DiGraphMap, prelude::NodeIndex,
+};
pub mod length;
pub mod nodes;
+use crate::types::nodes::primitives::color_matrix::{ColorMatrix, ColorMatrixType};
+
use self::{
length::{Coordinate, Length},
nodes::Node,
};
+#[derive(Debug)]
pub struct Filter<'a> {
- graph: DiGraphMap,
+ pub graph: DiGraph>,
+ source_graphic_idx: NodeIndex,
}
-pub enum Edge<'a> {
- Named(&'a str, u8),
+
+impl Filter<'_> {
+ pub fn new() -> Self {
+ let mut graph = DiGraph::new();
+ let source_graphic_idx = graph.add_node(Node::StdInput(
+ nodes::standard_input::StandardInput::SourceGraphic,
+ ));
+
+ Self {
+ graph,
+ source_graphic_idx,
+ }
+ }
+
+ pub fn add_node(&mut self, node: Node) -> NodeIndex {
+ self.graph.add_node(node)
+ }
+
+ pub fn source_graphic(&self) -> NodeIndex {
+ self.source_graphic_idx
+ }
+}
+
+impl Default for Filter<'_> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct Edge<'a> {
+ edge_type: EdgeType<'a>,
+ /// the index of the `in` attribute on the target element
+ /// if None, just `in`
+ in_idx: Option,
+}
+
+impl Edge<'_> {
+ pub fn new() -> Self {
+ Self {
+ edge_type: EdgeType::Unnamed,
+ in_idx: None,
+ }
+ }
+
+ pub fn in_idx(idx: u8) -> Self {
+ Self {
+ edge_type: EdgeType::Unnamed,
+ in_idx: Some(idx),
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum EdgeType<'a> {
+ Named(&'a str),
/// For standard inputs such as SourceGraphic etc., which we'll just be representing as nodes for simplicity
- Unnamed(u8),
+ Unnamed,
}
diff --git a/crates/svg-filters/src/types/length.rs b/crates/svg-filters/src/types/length.rs
index 4db3fd9..1186181 100644
--- a/crates/svg-filters/src/types/length.rs
+++ b/crates/svg-filters/src/types/length.rs
@@ -1,7 +1,10 @@
+#[derive(Default, Debug)]
pub struct Length(f32, Unit);
pub type Coordinate = Length;
+#[derive(Default, Debug)]
pub enum Unit {
+ #[default]
None,
Em,
Ex,
diff --git a/crates/svg-filters/src/types/nodes.rs b/crates/svg-filters/src/types/nodes.rs
index 3571e76..29982bc 100644
--- a/crates/svg-filters/src/types/nodes.rs
+++ b/crates/svg-filters/src/types/nodes.rs
@@ -1,13 +1,113 @@
-use self::{primitives::Primitive, standard_input::StandardInput};
+use self::{
+ primitives::{
+ blend::{Blend, BlendMode},
+ color_matrix::{ColorMatrix, ColorMatrixType},
+ composite::{Composite, CompositeOperator},
+ gaussian_blur::GaussianBlur,
+ offset::Offset,
+ FePrimitive,
+ },
+ standard_input::StandardInput,
+};
use super::length::{Coordinate, Length};
+pub mod primitives;
pub mod standard_input;
-pub mod primitives;
-
+#[derive(Debug)]
pub enum Node {
- /// We represent those as Nodes because they're essentially magical nodes
- StandardInput(StandardInput),
- Primitive(Primitive),
+ StdInput(StandardInput),
+ Primitive {
+ primitive: FePrimitive,
+ common_attrs: CommonAttrs,
+ },
+}
+
+impl Default for Node {
+ fn default() -> Self {
+ Self::StdInput(StandardInput::SourceGraphic)
+ }
+}
+
+#[derive(Default, Debug)]
+struct CommonAttrs {
+ x: Coordinate,
+ y: Coordinate,
+ width: Length,
+ height: Length,
+}
+
+impl Node {
+ pub fn simple(el: FePrimitive) -> Node {
+ Node::Primitive {
+ primitive: el,
+ common_attrs: CommonAttrs::default(),
+ }
+ }
+
+ pub fn input_count(&self) -> u8 {
+ match self {
+ Node::Primitive {
+ primitive:
+ FePrimitive::ColorMatrix(_)
+ | FePrimitive::ComponentTransfer(_)
+ | FePrimitive::ConvolveMatrix(_)
+ | FePrimitive::DiffuseLighting(_)
+ | FePrimitive::GaussianBlur(_)
+ | FePrimitive::Morphology(_)
+ | FePrimitive::Offset(_)
+ | FePrimitive::SpecularLighting(_)
+ | FePrimitive::Tile(_),
+ ..
+ } => 1,
+
+ Node::Primitive {
+ primitive:
+ FePrimitive::Composite(_) | FePrimitive::Blend(_) | FePrimitive::DisplacementMap(_),
+ ..
+ } => 2,
+
+ Node::StdInput(_)
+ | Node::Primitive {
+ primitive:
+ FePrimitive::Flood(_) | FePrimitive::Image(_) | FePrimitive::Turbulence(_),
+ ..
+ } => 0,
+ Node::Primitive {
+ primitive: FePrimitive::Merge(_),
+ ..
+ } => todo!(),
+ }
+ }
+
+ pub fn blend(mode: BlendMode) -> Self {
+ Self::simple(FePrimitive::Blend(Blend::new(mode)))
+ }
+
+ pub fn color_matrix(cm_type: ColorMatrixType) -> Self {
+ Self::simple(FePrimitive::ColorMatrix(ColorMatrix::new(cm_type)))
+ }
+
+ pub fn composite(op: CompositeOperator) -> Self {
+ Self::simple(FePrimitive::Composite(Composite::new(op)))
+ }
+
+ pub fn composite_arithmetic(k1: f32, k2: f32, k3: f32, k4: f32) -> Self {
+ Self::simple(FePrimitive::Composite(Composite::arithmetic(
+ k1, k2, k3, k4,
+ )))
+ }
+
+ pub fn gaussian_blur(v: u16) -> Self {
+ Self::simple(FePrimitive::GaussianBlur(GaussianBlur::single(v)))
+ }
+
+ pub fn gaussian_blur_xy(x: u16, y: u16) -> Self {
+ Self::simple(FePrimitive::GaussianBlur(GaussianBlur::with_xy(x, y)))
+ }
+
+ pub fn offset(dx: f32, dy: f32) -> Self {
+ Self::simple(FePrimitive::Offset(Offset::new(dx, dy)))
+ }
}
diff --git a/crates/svg-filters/src/types/nodes/primitives.rs b/crates/svg-filters/src/types/nodes/primitives.rs
index 433f190..6be79b3 100644
--- a/crates/svg-filters/src/types/nodes/primitives.rs
+++ b/crates/svg-filters/src/types/nodes/primitives.rs
@@ -1,36 +1,29 @@
use crate::types::length::{Coordinate, Length};
-mod blend;
-mod color_matrix;
-mod component_transfer;
-mod composite;
-mod convolve_matrix;
-mod diffuse_lighting;
-mod displacement_map;
-mod flood;
-mod gaussian_blur;
-mod image;
-mod merge;
-mod morphology;
-mod offset;
-mod specular_lighting;
-mod tile;
-mod turbulence;
+use self::blend::BlendMode;
-pub struct Primitive {
- primitive: FePrimitive,
- common_attrs: CommonAttrs,
-}
+use super::Node;
-struct CommonAttrs {
- x: Coordinate,
- y: Coordinate,
- width: Length,
- height: Length,
-}
+pub mod blend;
+pub mod color_matrix;
+pub mod component_transfer;
+pub mod composite;
+pub mod convolve_matrix;
+pub mod diffuse_lighting;
+pub mod displacement_map;
+pub mod flood;
+pub mod gaussian_blur;
+pub mod image;
+pub mod merge;
+pub mod morphology;
+pub mod offset;
+pub mod specular_lighting;
+pub mod tile;
+pub mod turbulence;
/// svg filter effects primitives
-enum FePrimitive {
+#[derive(Debug)]
+pub enum FePrimitive {
// 2 inputs
Blend(blend::Blend),
ColorMatrix(color_matrix::ColorMatrix),
diff --git a/crates/svg-filters/src/types/nodes/primitives/blend.rs b/crates/svg-filters/src/types/nodes/primitives/blend.rs
index c8972de..242f763 100644
--- a/crates/svg-filters/src/types/nodes/primitives/blend.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/blend.rs
@@ -1,10 +1,26 @@
/// [feBlend](https://www.w3.org/TR/SVG11/filters.html#feBlendElement)
-pub struct Blend {
+#[derive(Debug)]
+pub(in crate::types::nodes) struct Blend {
mode: BlendMode,
}
+impl Blend {
+ pub fn new(mode: BlendMode) -> Self {
+ Self { mode }
+ }
+}
+
+impl Default for Blend {
+ fn default() -> Self {
+ Self {
+ mode: BlendMode::Normal,
+ }
+ }
+}
+
/// as according to https://drafts.fxtf.org/compositing-1/#blending
-enum BlendMode {
+#[derive(Debug)]
+pub enum BlendMode {
Normal,
Multiply,
Screen,
diff --git a/crates/svg-filters/src/types/nodes/primitives/color_matrix.rs b/crates/svg-filters/src/types/nodes/primitives/color_matrix.rs
index bdc945e..fbae6b2 100644
--- a/crates/svg-filters/src/types/nodes/primitives/color_matrix.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/color_matrix.rs
@@ -1,19 +1,19 @@
/// [feColorMatrix](https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement)
+#[derive(Debug)]
pub struct ColorMatrix {
cm_type: ColorMatrixType,
}
-enum ColorMatrixType {
- Matrix {
- values: [f32; 20],
- },
- Saturate {
- // is the values attribute anyway tho
- value: f32,
- },
- HueRotate {
- // also the values attribute
- degrees: f32,
- },
+impl ColorMatrix {
+ pub fn new(cm_type: ColorMatrixType) -> Self {
+ Self { cm_type }
+ }
+}
+
+#[derive(Debug)]
+pub enum ColorMatrixType {
+ Matrix(Box<[f32; 20]>),
+ Saturate(f32),
+ HueRotate(f32),
LuminanceToAlpha,
}
diff --git a/crates/svg-filters/src/types/nodes/primitives/component_transfer.rs b/crates/svg-filters/src/types/nodes/primitives/component_transfer.rs
index 6c58d87..3ccc039 100644
--- a/crates/svg-filters/src/types/nodes/primitives/component_transfer.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/component_transfer.rs
@@ -1,4 +1,5 @@
/// [feComponentTransfer](https://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement)
+#[derive(Debug)]
pub struct ComponentTransfer {
func_r: TransferFunction,
func_g: TransferFunction,
@@ -7,6 +8,7 @@ pub struct ComponentTransfer {
}
/// [transfer functions](https://www.w3.org/TR/SVG11/filters.html#transferFuncElements)
+#[derive(Debug)]
enum TransferFunction {
Identity,
Table {
diff --git a/crates/svg-filters/src/types/nodes/primitives/composite.rs b/crates/svg-filters/src/types/nodes/primitives/composite.rs
index ae95447..c86de26 100644
--- a/crates/svg-filters/src/types/nodes/primitives/composite.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/composite.rs
@@ -1,9 +1,23 @@
/// [feComposite](https://www.w3.org/TR/SVG11/filters.html#feCompositeElement)
+#[derive(Debug)]
pub struct Composite {
operator: CompositeOperator,
}
-enum CompositeOperator {
+impl Composite {
+ pub fn new(op: CompositeOperator) -> Self {
+ Self { operator: op }
+ }
+
+ pub fn arithmetic(k1: f32, k2: f32, k3: f32, k4: f32) -> Self {
+ Self {
+ operator: CompositeOperator::Arithmetic { k1, k2, k3, k4 },
+ }
+ }
+}
+
+#[derive(Debug)]
+pub enum CompositeOperator {
Over,
In,
Out,
diff --git a/crates/svg-filters/src/types/nodes/primitives/convolve_matrix.rs b/crates/svg-filters/src/types/nodes/primitives/convolve_matrix.rs
index a619ac9..1fe2ef4 100644
--- a/crates/svg-filters/src/types/nodes/primitives/convolve_matrix.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/convolve_matrix.rs
@@ -1,3 +1,4 @@
+#[derive(Debug)]
pub struct ConvolveMatrix {
order: (u16, u16),
// must be checked to be `order.0 * order.1`
@@ -11,6 +12,7 @@ pub struct ConvolveMatrix {
preserve_alpha: bool,
}
+#[derive(Debug)]
enum EdgeMode {
None,
Duplicate,
diff --git a/crates/svg-filters/src/types/nodes/primitives/diffuse_lighting.rs b/crates/svg-filters/src/types/nodes/primitives/diffuse_lighting.rs
index 18a0485..5d9cd6f 100644
--- a/crates/svg-filters/src/types/nodes/primitives/diffuse_lighting.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/diffuse_lighting.rs
@@ -1,2 +1,3 @@
// TODO
+#[derive(Debug)]
pub struct DiffuseLighting;
diff --git a/crates/svg-filters/src/types/nodes/primitives/displacement_map.rs b/crates/svg-filters/src/types/nodes/primitives/displacement_map.rs
index e59a520..b6485ac 100644
--- a/crates/svg-filters/src/types/nodes/primitives/displacement_map.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/displacement_map.rs
@@ -1,10 +1,12 @@
/// [feDisplacementMap](https://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement)
+#[derive(Debug)]
pub struct DisplacementMap {
scale: f32,
x_channel_selector: Channel,
y_channel_selector: Channel,
}
+#[derive(Debug)]
enum Channel {
A,
R,
diff --git a/crates/svg-filters/src/types/nodes/primitives/flood.rs b/crates/svg-filters/src/types/nodes/primitives/flood.rs
index 6858c71..94f6eee 100644
--- a/crates/svg-filters/src/types/nodes/primitives/flood.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/flood.rs
@@ -1,6 +1,7 @@
use csscolorparser::Color;
/// [feFlood](https://www.w3.org/TR/SVG11/filters.html#feFloodElement)
+#[derive(Debug)]
pub struct Flood {
flood_color: Color,
flood_opacity: f32,
diff --git a/crates/svg-filters/src/types/nodes/primitives/gaussian_blur.rs b/crates/svg-filters/src/types/nodes/primitives/gaussian_blur.rs
index 5ad8047..e6ca9c1 100644
--- a/crates/svg-filters/src/types/nodes/primitives/gaussian_blur.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/gaussian_blur.rs
@@ -1,4 +1,19 @@
/// [feGaussianBlur](https://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement)
+#[derive(Debug)]
pub struct GaussianBlur {
- std_deviation: (f32, f32),
+ std_deviation: (u16, u16),
+}
+
+impl GaussianBlur {
+ pub fn single(v: u16) -> Self {
+ Self {
+ std_deviation: (v, v),
+ }
+ }
+
+ pub fn with_xy(x: u16, y: u16) -> Self {
+ Self {
+ std_deviation: (x, y),
+ }
+ }
}
diff --git a/crates/svg-filters/src/types/nodes/primitives/image.rs b/crates/svg-filters/src/types/nodes/primitives/image.rs
index d068c89..c52c0b7 100644
--- a/crates/svg-filters/src/types/nodes/primitives/image.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/image.rs
@@ -1,2 +1,3 @@
// TODO
+#[derive(Debug)]
pub struct Image;
diff --git a/crates/svg-filters/src/types/nodes/primitives/merge.rs b/crates/svg-filters/src/types/nodes/primitives/merge.rs
index a65df6e..ab26374 100644
--- a/crates/svg-filters/src/types/nodes/primitives/merge.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/merge.rs
@@ -1,2 +1,3 @@
// TODO
+#[derive(Debug)]
pub struct Merge;
diff --git a/crates/svg-filters/src/types/nodes/primitives/morphology.rs b/crates/svg-filters/src/types/nodes/primitives/morphology.rs
index 6fd50e1..6b33825 100644
--- a/crates/svg-filters/src/types/nodes/primitives/morphology.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/morphology.rs
@@ -1,9 +1,11 @@
/// [feMorphology](https://www.w3.org/TR/SVG11/filters.html#feMorphologyElement)
+#[derive(Debug)]
pub struct Morphology {
operator: Operator,
radius: (f32, f32),
}
+#[derive(Debug)]
enum Operator {
Erode,
Dilate,
diff --git a/crates/svg-filters/src/types/nodes/primitives/offset.rs b/crates/svg-filters/src/types/nodes/primitives/offset.rs
index 1473b0e..96b47ef 100644
--- a/crates/svg-filters/src/types/nodes/primitives/offset.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/offset.rs
@@ -1,5 +1,12 @@
/// [feOffset](https://www.w3.org/TR/SVG11/filters.html#feOffsetElement)
+#[derive(Debug)]
pub struct Offset {
dx: f32,
dy: f32,
}
+
+impl Offset {
+ pub fn new(dx: f32, dy: f32) -> Self {
+ Self { dx, dy }
+ }
+}
diff --git a/crates/svg-filters/src/types/nodes/primitives/specular_lighting.rs b/crates/svg-filters/src/types/nodes/primitives/specular_lighting.rs
index ab41f49..16a6fcc 100644
--- a/crates/svg-filters/src/types/nodes/primitives/specular_lighting.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/specular_lighting.rs
@@ -1,2 +1,3 @@
// TODO
+#[derive(Debug)]
pub struct SpecularLighting;
diff --git a/crates/svg-filters/src/types/nodes/primitives/tile.rs b/crates/svg-filters/src/types/nodes/primitives/tile.rs
index b943271..7a957c5 100644
--- a/crates/svg-filters/src/types/nodes/primitives/tile.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/tile.rs
@@ -1,2 +1,3 @@
/// [feTile](https://www.w3.org/TR/SVG11/filters.html#feTileElement)
+#[derive(Debug)]
pub struct Tile;
diff --git a/crates/svg-filters/src/types/nodes/primitives/turbulence.rs b/crates/svg-filters/src/types/nodes/primitives/turbulence.rs
index 998b472..ec815cb 100644
--- a/crates/svg-filters/src/types/nodes/primitives/turbulence.rs
+++ b/crates/svg-filters/src/types/nodes/primitives/turbulence.rs
@@ -1,4 +1,5 @@
/// [feTurbulence](https://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement)
+#[derive(Debug)]
pub struct Turbulence {
base_frequency: (f32, f32),
num_octaves: (u16),
@@ -8,10 +9,12 @@ pub struct Turbulence {
noise_type: NoiseType,
}
+#[derive(Debug)]
enum StitchTiles {
Stitch,
NoStitch,
}
+#[derive(Debug)]
enum NoiseType {
Turbulence,
FractalNoise,
diff --git a/crates/svg-filters/src/types/nodes/standard_input.rs b/crates/svg-filters/src/types/nodes/standard_input.rs
index e1ae7d1..add10d0 100644
--- a/crates/svg-filters/src/types/nodes/standard_input.rs
+++ b/crates/svg-filters/src/types/nodes/standard_input.rs
@@ -1,5 +1,6 @@
/// [svg filter effect standard input](https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveInAttribute)
/// technically not a node, but for implementation simplicity... yeah
+#[derive(Debug)]
pub enum StandardInput {
SourceGraphic,
SourceAlpha,