1use std::sync::Arc;
4
5use crate::buf::{OpaqueValue, RasterBuf, ScalarField};
6use crate::port::PortKind;
7
8#[derive(Debug, Clone)]
10pub enum PortValue {
11 Features(OpaqueValue),
12 Raster(Arc<RasterBuf>),
13 Sprite(Arc<RasterBuf>),
14 Brush(OpaqueValue),
15 Labels(OpaqueValue),
17 Scalar(ScalarValue),
18 ScalarField(Arc<ScalarField>),
19}
20
21impl PortValue {
22 pub fn kind(&self) -> PortKind {
23 match self {
24 PortValue::Features(_) => PortKind::Features,
25 PortValue::Raster(_) => PortKind::Raster,
26 PortValue::Sprite(_) => PortKind::Sprite,
27 PortValue::Brush(_) => PortKind::Brush,
28 PortValue::Labels(_) => PortKind::Labels,
29 PortValue::Scalar(_) => PortKind::Scalar,
30 PortValue::ScalarField(_) => PortKind::ScalarField,
31 }
32 }
33
34 pub fn as_scalar_field(&self) -> Option<&Arc<ScalarField>> {
35 if let PortValue::ScalarField(f) = self {
36 Some(f)
37 } else {
38 None
39 }
40 }
41
42 pub fn as_raster(&self) -> Option<&Arc<RasterBuf>> {
43 if let PortValue::Raster(r) = self {
44 Some(r)
45 } else {
46 None
47 }
48 }
49
50 pub fn as_sprite(&self) -> Option<&Arc<RasterBuf>> {
51 if let PortValue::Sprite(s) = self {
52 Some(s)
53 } else {
54 None
55 }
56 }
57
58 pub fn approx_bytes(&self) -> usize {
69 match self {
70 PortValue::Raster(r) | PortValue::Sprite(r) => {
71 if RasterBuf::is_interned_blank(r) {
72 0
73 } else {
74 r.pixels.len()
75 }
76 }
77 PortValue::ScalarField(f) => f.values.len() * std::mem::size_of::<f32>(),
78 _ => 0,
79 }
80 }
81
82 pub fn as_scalar(&self) -> Option<&ScalarValue> {
83 if let PortValue::Scalar(s) = self {
84 Some(s)
85 } else {
86 None
87 }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq)]
93pub enum ScalarValue {
94 Color([f32; 4]),
98 Number(f64),
99 Bool(bool),
100}
101
102impl ScalarValue {
103 pub fn as_color(&self) -> Option<[f32; 4]> {
104 if let ScalarValue::Color(c) = self {
105 Some(*c)
106 } else {
107 None
108 }
109 }
110
111 pub fn as_number(&self) -> Option<f64> {
112 if let ScalarValue::Number(n) = self {
113 Some(*n)
114 } else {
115 None
116 }
117 }
118
119 pub fn as_bool(&self) -> Option<bool> {
120 if let ScalarValue::Bool(b) = self {
121 Some(*b)
122 } else {
123 None
124 }
125 }
126
127 pub fn kind_name(&self) -> &'static str {
129 match self {
130 ScalarValue::Color(_) => "color",
131 ScalarValue::Number(_) => "number",
132 ScalarValue::Bool(_) => "bool",
133 }
134 }
135
136 pub fn hash_into(&self, h: &mut xxhash_rust::xxh3::Xxh3) {
138 match self {
139 ScalarValue::Color(c) => {
140 h.update(b"C");
141 for ch in c {
142 h.update(&ch.to_le_bytes());
143 }
144 }
145 ScalarValue::Number(n) => {
146 h.update(b"N");
147 h.update(&n.to_le_bytes());
148 }
149 ScalarValue::Bool(b) => {
150 h.update(b"B");
151 h.update(&[*b as u8]);
152 }
153 }
154 }
155}