polydat_core/iteration/comprehension/
streamer_value.rs1use serde::{Deserialize, Serialize};
16
17use crate::ast::{ReflectedValue, Value};
18use crate::iteration::comprehension::ast::Comprehension;
19use crate::iteration::comprehension::cardinality::CardinalityClass;
20use crate::iteration::comprehension::metadata::Metadata;
21use crate::iteration::comprehension::surfaces::{CompiledComprehension, CoordinateStream, compile};
22use crate::iteration::comprehension::validate::ValidationError;
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26pub struct StreamerValue {
27 pub text: String,
30 pub ast: Comprehension,
32}
33
34impl StreamerValue {
35 pub fn new(text: impl Into<String>, ast: Comprehension) -> Self {
37 Self {
38 text: text.into(),
39 ast,
40 }
41 }
42
43 pub fn element_names(&self) -> Vec<String> {
45 self.ast.coordinate_names()
46 }
47
48 pub fn metadata(&self) -> Metadata {
51 self.ast.metadata()
52 }
53
54 pub fn cardinality(&self) -> CardinalityClass {
56 self.metadata().cardinality
57 }
58
59 pub fn compiled(&self) -> Result<CompiledComprehension, ValidationError> {
66 compile(&self.ast)
67 }
68
69 pub fn coordinate_stream(&self) -> Result<CoordinateStream, ValidationError> {
71 Ok(self.compiled()?.coordinate_stream())
72 }
73
74 pub fn to_json(&self) -> String {
77 serde_json::to_string(self).expect("StreamerValue serializes")
78 }
79
80 pub fn from_json(payload: &str) -> Self {
85 let trimmed = payload.trim();
86 if trimmed.starts_with('{') {
87 match serde_json::from_str::<Self>(trimmed) {
88 Ok(v) => return v,
89 Err(e) => panic!("streamer: malformed comprehension payload: {e}"),
90 }
91 }
92 match Self::parse_text(trimmed) {
93 Ok(v) => v,
94 Err(e) => panic!("streamer: `{trimmed}` is not a comprehension: {e}"),
95 }
96 }
97
98 pub fn parse_text(text: &str) -> Result<Self, String> {
100 let ast = crate::iteration::comprehension::spec::parse_comprehension_algebra(text)?;
101 Ok(Self::new(text, ast))
102 }
103}
104
105impl ReflectedValue for StreamerValue {
106 fn type_name(&self) -> &str {
107 "Streamer"
108 }
109
110 fn display(&self) -> String {
111 format!("for {}", self.text)
112 }
113
114 fn to_json_value(&self) -> serde_json::Value {
115 serde_json::json!({
116 "for": self.text,
117 "elements": self.element_names(),
118 "cardinality": format!("{:?}", self.cardinality()),
119 })
120 }
121
122 fn as_any(&self) -> &dyn std::any::Any {
123 self
124 }
125
126 fn clone_reflected(&self) -> Box<dyn ReflectedValue> {
127 Box::new(self.clone())
128 }
129}
130
131impl Value {
132 pub fn from_streamer(s: StreamerValue) -> Self {
134 Value::Ext(Box::new(s))
135 }
136
137 pub fn as_streamer(&self) -> Option<&StreamerValue> {
140 match self {
141 Value::Ext(b) => b.as_any().downcast_ref::<StreamerValue>(),
142 _ => None,
143 }
144 }
145}