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