polydat_core/iteration/comprehension/
streamer_value.rs1use serde::{Deserialize, Serialize};
15
16use crate::ast::{ReflectedValue, Value};
17use crate::iteration::comprehension::ast::Comprehension;
18use crate::iteration::comprehension::cardinality::CardinalityClass;
19use crate::iteration::comprehension::metadata::Metadata;
20use crate::iteration::comprehension::surfaces::{CompiledComprehension, CoordinateStream, compile};
21
22#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
24pub struct StreamerValue {
25 pub text: String,
28 pub ast: Comprehension,
30}
31
32impl StreamerValue {
33 pub fn new(text: impl Into<String>, ast: Comprehension) -> Self {
35 Self {
36 text: text.into(),
37 ast,
38 }
39 }
40
41 pub fn element_names(&self) -> Vec<String> {
43 self.ast.coordinate_names()
44 }
45
46 pub fn metadata(&self) -> Metadata {
49 self.ast.metadata()
50 }
51
52 pub fn cardinality(&self) -> CardinalityClass {
54 self.metadata().cardinality
55 }
56
57 pub fn compiled(&self) -> CompiledComprehension {
59 compile(&self.ast)
60 }
61
62 pub fn coordinate_stream(&self) -> CoordinateStream {
64 self.compiled().coordinate_stream()
65 }
66
67 pub fn to_json(&self) -> String {
70 serde_json::to_string(self).expect("StreamerValue serializes")
71 }
72
73 pub fn from_json(payload: &str) -> Self {
78 let trimmed = payload.trim();
79 if trimmed.starts_with('{') {
80 match serde_json::from_str::<Self>(trimmed) {
81 Ok(v) => return v,
82 Err(e) => panic!("streamer: malformed comprehension payload: {e}"),
83 }
84 }
85 match Self::parse_text(trimmed) {
86 Ok(v) => v,
87 Err(e) => panic!("streamer: `{trimmed}` is not a comprehension: {e}"),
88 }
89 }
90
91 pub fn parse_text(text: &str) -> Result<Self, String> {
93 let legacy = crate::iteration::comprehension::parse::parse_comprehension_text(text)?;
94 let ast = crate::iteration::comprehension::spec::legacy_to_algebra(&legacy)
95 .map_err(|e| e.to_string())?;
96 Ok(Self::new(text, ast))
97 }
98}
99
100impl ReflectedValue for StreamerValue {
101 fn type_name(&self) -> &str {
102 "Streamer"
103 }
104
105 fn display(&self) -> String {
106 format!("for {}", self.text)
107 }
108
109 fn to_json_value(&self) -> serde_json::Value {
110 serde_json::json!({
111 "for": self.text,
112 "elements": self.element_names(),
113 "cardinality": format!("{:?}", self.cardinality()),
114 })
115 }
116
117 fn as_any(&self) -> &dyn std::any::Any {
118 self
119 }
120
121 fn clone_reflected(&self) -> Box<dyn ReflectedValue> {
122 Box::new(self.clone())
123 }
124}
125
126impl Value {
127 pub fn from_streamer(s: StreamerValue) -> Self {
129 Value::Ext(Box::new(s))
130 }
131
132 pub fn as_streamer(&self) -> Option<&StreamerValue> {
135 match self {
136 Value::Ext(b) => b.as_any().downcast_ref::<StreamerValue>(),
137 _ => None,
138 }
139 }
140}