Skip to content

Commit 0c66e1c

Browse files
committed
feat(py): add verbose option for detailed output in spec getter
1 parent 5c0c1f9 commit 0c66e1c

File tree

2 files changed

+262
-84
lines changed

2 files changed

+262
-84
lines changed

src/base/spec.rs

Lines changed: 183 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::prelude::*;
22

3-
use super::schema::{EnrichedValueType, FieldSchema, ValueType};
3+
use super::schema::{EnrichedValueType, FieldSchema};
44
use serde::{Deserialize, Serialize};
5+
use serde_json::Value;
56
use std::fmt;
67
use std::ops::Deref;
78

@@ -115,9 +116,8 @@ pub struct ConstantMapping {
115116

116117
impl fmt::Display for ConstantMapping {
117118
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118-
let schema = format_value_type(&self.schema);
119119
let value = serde_json::to_string(&self.value).unwrap_or("#serde_error".to_string());
120-
write!(f, "Constant({}: {})", value, schema)
120+
write!(f, "{}", value)
121121
}
122122
}
123123

@@ -137,10 +137,10 @@ impl fmt::Display for StructMapping {
137137
let fields = self
138138
.fields
139139
.iter()
140-
.map(|field| format!("{}={}", field.name, field.spec))
140+
.map(|field| field.name.clone())
141141
.collect::<Vec<_>>()
142-
.join(", ");
143-
write!(f, "[{}]", fields)
142+
.join(",");
143+
write!(f, "{}", fields)
144144
}
145145
}
146146

@@ -216,11 +216,41 @@ pub struct OpSpec {
216216
pub spec: serde_json::Map<String, serde_json::Value>,
217217
}
218218

219-
impl fmt::Display for OpSpec {
220-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219+
impl OpSpec {
220+
pub fn format_concise(&self) -> String {
221+
let mut parts = vec![];
222+
for (key, value) in self.spec.iter() {
223+
match value {
224+
Value::String(s) => parts.push(format!("{}={}", key, s)),
225+
Value::Array(arr) => {
226+
let items = arr
227+
.iter()
228+
.filter_map(|v| v.as_str())
229+
.collect::<Vec<_>>()
230+
.join(",");
231+
if !items.is_empty() {
232+
parts.push(format!("{}={}", key, items));
233+
}
234+
}
235+
Value::Object(obj) => {
236+
if let Some(model) = obj.get("model").and_then(|v| v.as_str()) {
237+
parts.push(format!("{}={}", key, model));
238+
}
239+
}
240+
_ => {}
241+
}
242+
}
243+
if parts.is_empty() {
244+
self.kind.clone()
245+
} else {
246+
format!("{}({})", self.kind, parts.join(", "))
247+
}
248+
}
249+
250+
pub fn format_verbose(&self) -> String {
221251
let spec_str = serde_json::to_string_pretty(&self.spec)
222252
.map(|s| {
223-
let lines: Vec<&str> = s.lines().take(50).collect();
253+
let lines: Vec<&str> = s.lines().collect();
224254
if lines.len() < s.lines().count() {
225255
lines
226256
.into_iter()
@@ -232,7 +262,13 @@ impl fmt::Display for OpSpec {
232262
}
233263
})
234264
.unwrap_or("#serde_error".to_string());
235-
write!(f, "OpSpec: kind={}, spec={}", self.kind, spec_str)
265+
format!("{}({})", self.kind, spec_str)
266+
}
267+
}
268+
269+
impl fmt::Display for OpSpec {
270+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271+
write!(f, "{}", self.format_concise())
236272
}
237273
}
238274

@@ -246,7 +282,7 @@ impl fmt::Display for SourceRefreshOptions {
246282
let refresh = self
247283
.refresh_interval
248284
.map(|d| format!("{:?}", d))
249-
.unwrap_or("None".to_string());
285+
.unwrap_or("none".to_string());
250286
write!(f, "{}", refresh)
251287
}
252288
}
@@ -259,13 +295,28 @@ pub struct ImportOpSpec {
259295
pub refresh_options: SourceRefreshOptions,
260296
}
261297

298+
impl ImportOpSpec {
299+
fn format(&self, verbose: bool) -> String {
300+
let source = if verbose {
301+
self.source.format_verbose()
302+
} else {
303+
self.source.format_concise()
304+
};
305+
format!("source={}, refresh={}", source, self.refresh_options)
306+
}
307+
308+
pub fn format_concise(&self) -> String {
309+
self.format(false)
310+
}
311+
312+
pub fn format_verbose(&self) -> String {
313+
self.format(true)
314+
}
315+
}
316+
262317
impl fmt::Display for ImportOpSpec {
263318
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
264-
write!(
265-
f,
266-
"Import: source={}, refresh={}",
267-
self.source, self.refresh_options
268-
)
319+
write!(f, "{}", self.format_concise())
269320
}
270321
}
271322

@@ -275,15 +326,40 @@ pub struct TransformOpSpec {
275326
pub op: OpSpec,
276327
}
277328

278-
impl fmt::Display for TransformOpSpec {
279-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329+
impl TransformOpSpec {
330+
fn format(&self, verbose: bool) -> String {
280331
let inputs = self
281332
.inputs
282333
.iter()
283-
.map(|input| input.to_string())
334+
.map(ToString::to_string)
284335
.collect::<Vec<_>>()
285-
.join(", ");
286-
write!(f, "Transform: op={}, inputs=[{}]", self.op, inputs)
336+
.join(",");
337+
338+
let op_str = if verbose {
339+
self.op.format_verbose()
340+
} else {
341+
self.op.format_concise()
342+
};
343+
344+
if verbose {
345+
format!("op={}, inputs=[{}]", op_str, inputs)
346+
} else {
347+
format!("op={}, inputs={}", op_str, inputs)
348+
}
349+
}
350+
351+
pub fn format_concise(&self) -> String {
352+
self.format(false)
353+
}
354+
355+
pub fn format_verbose(&self) -> String {
356+
self.format(true)
357+
}
358+
}
359+
360+
impl fmt::Display for TransformOpSpec {
361+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
362+
write!(f, "{}", self.format_concise())
287363
}
288364
}
289365

@@ -294,9 +370,15 @@ pub struct ForEachOpSpec {
294370
pub op_scope: ReactiveOpScope,
295371
}
296372

373+
impl ForEachOpSpec {
374+
pub fn get_label(&self) -> String {
375+
format!("Loop over {}", self.field_path)
376+
}
377+
}
378+
297379
impl fmt::Display for ForEachOpSpec {
298380
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299-
write!(f, "ForEach: field={}", self.field_path)
381+
write!(f, "field={}", self.field_path)
300382
}
301383
}
302384

@@ -313,13 +395,35 @@ pub struct CollectOpSpec {
313395
pub auto_uuid_field: Option<FieldName>,
314396
}
315397

398+
impl CollectOpSpec {
399+
fn format(&self, verbose: bool) -> String {
400+
let uuid = self.auto_uuid_field.as_deref().unwrap_or("none");
401+
402+
if verbose {
403+
format!(
404+
"scope={}, collector={}, input=[{}], uuid={}",
405+
self.scope_name, self.collector_name, self.input, uuid
406+
)
407+
} else {
408+
format!(
409+
"collector={}, input={}, uuid={}",
410+
self.collector_name, self.input, uuid
411+
)
412+
}
413+
}
414+
415+
pub fn format_concise(&self) -> String {
416+
self.format(false)
417+
}
418+
419+
pub fn format_verbose(&self) -> String {
420+
self.format(true)
421+
}
422+
}
423+
316424
impl fmt::Display for CollectOpSpec {
317425
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318-
write!(
319-
f,
320-
"Collect: scope={}, collector={}, input={}, uuid_field={:?}",
321-
self.scope_name, self.collector_name, self.input, self.auto_uuid_field
322-
)
426+
write!(f, "{}", self.format_concise())
323427
}
324428
}
325429

@@ -365,19 +469,15 @@ impl fmt::Display for IndexOptions {
365469
let primary_keys = self
366470
.primary_key_fields
367471
.as_ref()
368-
.map(|p| p.join(", "))
472+
.map(|p| p.join(","))
369473
.unwrap_or_default();
370474
let vector_indexes = self
371475
.vector_indexes
372476
.iter()
373477
.map(|v| v.to_string())
374478
.collect::<Vec<_>>()
375-
.join(", ");
376-
write!(
377-
f,
378-
"IndexOptions: primary_keys=[{}], vector_indexes=[{}]",
379-
primary_keys, vector_indexes
380-
)
479+
.join(",");
480+
write!(f, "keys={}, indexes={}", primary_keys, vector_indexes)
381481
}
382482
}
383483

@@ -389,13 +489,38 @@ pub struct ExportOpSpec {
389489
pub setup_by_user: bool,
390490
}
391491

492+
impl ExportOpSpec {
493+
fn format(&self, verbose: bool) -> String {
494+
let target_str = if verbose {
495+
self.target.format_verbose()
496+
} else {
497+
self.target.format_concise()
498+
};
499+
500+
let base = format!(
501+
"collector={}, target={}, {}",
502+
self.collector_name, target_str, self.index_options
503+
);
504+
505+
if verbose {
506+
format!("{}, setup_by_user={}", base, self.setup_by_user)
507+
} else {
508+
base
509+
}
510+
}
511+
512+
pub fn format_concise(&self) -> String {
513+
self.format(false)
514+
}
515+
516+
pub fn format_verbose(&self) -> String {
517+
self.format(true)
518+
}
519+
}
520+
392521
impl fmt::Display for ExportOpSpec {
393522
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
394-
write!(
395-
f,
396-
"Export: collector={}, target={}, {}, setup_by_user={}",
397-
self.collector_name, self.target, self.index_options, self.setup_by_user
398-
)
523+
write!(f, "{}", self.format_concise())
399524
}
400525
}
401526

@@ -407,16 +532,30 @@ pub enum ReactiveOpSpec {
407532
Collect(CollectOpSpec),
408533
}
409534

410-
impl fmt::Display for ReactiveOpSpec {
411-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
535+
impl ReactiveOpSpec {
536+
pub fn format_concise(&self) -> String {
537+
match self {
538+
ReactiveOpSpec::Transform(t) => format!("Transform: {}", t.format_concise()),
539+
ReactiveOpSpec::ForEach(fe) => format!("{}", fe.get_label()),
540+
ReactiveOpSpec::Collect(c) => c.format_concise(),
541+
}
542+
}
543+
544+
pub fn format_verbose(&self) -> String {
412545
match self {
413-
ReactiveOpSpec::Transform(t) => write!(f, "{}", t),
414-
ReactiveOpSpec::ForEach(fe) => write!(f, "{}", fe),
415-
ReactiveOpSpec::Collect(c) => write!(f, "{}", c),
546+
ReactiveOpSpec::Transform(t) => format!("Transform: {}", t.format_verbose()),
547+
ReactiveOpSpec::ForEach(fe) => format!("ForEach: {}", fe),
548+
ReactiveOpSpec::Collect(c) => format!("Collect: {}", c.format_verbose()),
416549
}
417550
}
418551
}
419552

553+
impl fmt::Display for ReactiveOpSpec {
554+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
555+
write!(f, "{}", self.format_concise())
556+
}
557+
}
558+
420559
#[derive(Debug, Clone, Serialize, Deserialize)]
421560
pub struct ReactiveOpScope {
422561
pub name: ScopeName,
@@ -531,16 +670,3 @@ impl<T> std::hash::Hash for AuthEntryReference<T> {
531670
self.key.hash(state);
532671
}
533672
}
534-
535-
// Helper function to format EnrichedValueType
536-
fn format_value_type(value_type: &EnrichedValueType) -> String {
537-
let mut typ = match &value_type.typ {
538-
ValueType::Basic(basic) => format!("{}", basic),
539-
ValueType::Table(t) => format!("{}", t.kind),
540-
ValueType::Struct(s) => format!("{}", s),
541-
};
542-
if value_type.nullable {
543-
typ.push('?');
544-
}
545-
typ
546-
}

0 commit comments

Comments
 (0)