1#![cfg_attr(not(test), warn(missing_docs))]
24#![warn(dead_code)]
25
26use crate::{
27 calendar::{date_time_to_pspp, time_to_pspp},
28 data::{ByteString, Datum, EncodedString, WithEncoding},
29 format::{self, DATETIME40_0, Decimal, F8_2, F40, Format, TIME40_0, Type, UncheckedFormat},
30 output::pivot::{
31 Footnote, FootnoteMarkerType,
32 look::{CellStyle, FontStyle},
33 },
34 settings::{Settings, Show},
35 spv::html::Markup,
36 variable::{VarType, Variable},
37};
38use chrono::{NaiveDateTime, NaiveTime};
39use itertools::Itertools;
40use serde::{
41 Serialize, Serializer,
42 ser::{SerializeMap, SerializeStruct},
43};
44use std::{
45 borrow::Borrow,
46 fmt::{Debug, Display, Write},
47 iter::{once, repeat},
48 sync::Arc,
49};
50
51#[derive(Clone, Default, PartialEq)]
56pub struct Value {
57 pub inner: ValueInner,
59
60 pub styling: Option<Box<ValueStyle>>,
62}
63
64impl Serialize for Value {
65 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66 where
67 S: serde::Serializer,
68 {
69 self.inner.serialize(serializer)
70 }
71}
72#[derive(Copy, Clone, Debug, Default, PartialEq)]
82pub struct BareValue<T>(pub T);
83impl<T> Serialize for BareValue<T>
84where
85 T: Borrow<Value>,
86{
87 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
88 where
89 S: Serializer,
90 {
91 let value = self.0.borrow();
92 match &value.inner {
93 ValueInner::Datum(datum_value) => datum_value.serialize_bare(serializer),
94 ValueInner::Variable(variable_value) => variable_value.var_name.serialize(serializer),
95 ValueInner::Text(text_value) => text_value.localized.serialize(serializer),
96 ValueInner::Markup(markup) => markup.serialize(serializer),
97 ValueInner::Template(_) => value.display(()).to_string().serialize(serializer),
98 ValueInner::Empty => ().serialize(serializer),
99 }
100 }
101}
102impl Value {
103 pub fn new(inner: ValueInner) -> Self {
107 Self {
108 inner,
109 styling: None,
110 }
111 }
112
113 pub fn new_number(number: Option<f64>) -> Self {
126 Self::new(ValueInner::Datum(DatumValue::new_number(number)))
127 }
128
129 pub fn new_integer(x: Option<f64>) -> Self {
131 Self::new_number(x).with_format(F40)
132 }
133
134 pub fn new_date(date_time: NaiveDateTime) -> Self {
138 Self::new_number(Some(date_time_to_pspp(date_time))).with_format(DATETIME40_0)
139 }
140
141 pub fn new_time(time: NaiveTime) -> Self {
145 Self::new_number(Some(time_to_pspp(time))).with_format(TIME40_0)
146 }
147
148 pub fn new_text(s: impl Into<String>) -> Self {
155 Self::new_user_text(s)
156 }
157
158 pub fn new_general_text(localized: String, c: String, id: String, user_provided: bool) -> Self {
162 Self::new(ValueInner::Text(TextValue {
163 user_provided,
164 c: (c != localized).then_some(c),
165 id: (id != localized).then_some(id),
166 localized,
167 }))
168 }
169
170 pub fn new_markup(markup: Markup) -> Self {
172 Self::new(ValueInner::Markup(markup))
173 }
174
175 pub fn new_user_text(s: impl Into<String>) -> Self {
178 Self::new(ValueInner::new_user_text(s))
179 }
180
181 pub fn new_variable(variable: &Variable) -> Self {
183 Self::new(ValueInner::Variable(VariableValue {
184 show: None,
185 var_name: String::from(variable.name.as_str()),
186 variable_label: variable.label.clone(),
187 }))
188 }
189
190 pub fn new_datum<B>(datum: &Datum<B>) -> Self
203 where
204 B: EncodedString,
205 {
206 Self::new(ValueInner::Datum(DatumValue::new(datum)))
207 }
208
209 pub const fn new_empty() -> Self {
211 Value {
213 inner: ValueInner::Empty,
214 styling: None,
215 }
216 }
217
218 pub const fn static_empty() -> &'static Self {
220 static EMPTY: Value = Value::new_empty();
221 &EMPTY
222 }
223
224 pub const fn is_empty(&self) -> bool {
226 self.inner.is_empty() && self.styling.is_none()
227 }
228
229 pub fn with_source_variable(self, variable: &Variable) -> Self {
232 let value_label = self
233 .datum()
234 .and_then(|datum| variable.value_labels.get(&datum).map(String::from));
235 self.with_value_label(value_label)
236 .with_format(variable.print_format)
237 .with_variable_name(Some(variable.name.as_str().into()))
238 }
239
240 pub fn with_format(self, format: impl Into<ValueFormat>) -> Self {
243 Self {
244 inner: self.inner.with_format(format),
245 ..self
246 }
247 }
248
249 pub fn new_datum_from_variable(datum: &Datum<ByteString>, variable: &Variable) -> Self {
251 Self::new_datum(&datum.as_encoded(variable.encoding())).with_source_variable(variable)
252 }
253
254 pub fn datum(&self) -> Option<&Datum<WithEncoding<ByteString>>> {
256 self.inner.datum()
257 }
258
259 pub fn with_footnote(mut self, footnote: &Arc<Footnote>) -> Self {
261 self.add_footnote(footnote);
262 self
263 }
264
265 pub fn with_footnotes<'a>(
267 mut self,
268 footnotes: impl IntoIterator<Item = &'a Arc<Footnote>>,
269 ) -> Self {
270 for footnote in footnotes {
271 self.add_footnote(footnote);
272 }
273 self
274 }
275
276 pub fn add_footnote(&mut self, footnote: &Arc<Footnote>) {
278 let footnotes = &mut self.styling_mut().footnotes;
279 footnotes.push(footnote.clone());
280 footnotes.sort_by_key(|f| f.index);
281 }
282
283 pub fn clear_footnotes(&mut self) {
285 if let Some(styling) = &mut self.styling
286 && !styling.footnotes.is_empty()
287 {
288 styling.footnotes.clear();
289 if styling.is_empty() {
290 self.styling = None;
291 }
292 }
293 }
294
295 pub fn with_subscripts<'a>(
297 mut self,
298 subscripts: impl IntoIterator<Item = impl Into<String>>,
299 ) -> Self {
300 self.styling_mut()
301 .subscripts
302 .extend(subscripts.into_iter().map(|s| s.into()));
303 self
304 }
305
306 pub fn with_subscript(mut self, subscript: impl Into<String>) -> Self {
308 self.add_subscript(subscript);
309 self
310 }
311
312 pub fn add_subscript(&mut self, subscript: impl Into<String>) {
314 self.styling_mut().subscripts.push(subscript.into());
315 }
316
317 pub fn with_show_value_label(mut self, show: Option<Show>) -> Self {
320 if let Some(datum_value) = self.inner.as_datum_value_mut() {
321 datum_value.show = show;
322 }
323 self
324 }
325
326 pub fn with_value_label(mut self, value_label: Option<String>) -> Self {
334 if let Some(datum_value) = self.inner.as_datum_value_mut() {
335 datum_value.value_label = value_label.clone()
336 }
337 self
338 }
339
340 pub fn with_variable_name(mut self, variable_name: Option<String>) -> Self {
348 if let Some(datum_value) = self.inner.as_datum_value_mut() {
349 datum_value.variable = variable_name.clone()
350 }
351 self
352 }
353
354 pub fn with_show_variable_label(mut self, show: Option<Show>) -> Self {
357 if let ValueInner::Variable(variable_value) = &mut self.inner {
358 variable_value.show = show;
359 }
360 self
361 }
362
363 pub fn with_font_style(mut self, font_style: FontStyle) -> Self {
365 self.set_font_style(font_style);
366 self
367 }
368
369 pub fn set_font_style(&mut self, font_style: FontStyle) {
371 self.styling_mut().font_style = Some(font_style);
372 }
373
374 pub fn with_cell_style(mut self, cell_style: CellStyle) -> Self {
376 self.set_cell_style(cell_style);
377 self
378 }
379
380 pub fn set_cell_style(&mut self, cell_style: CellStyle) {
382 self.styling_mut().cell_style = Some(cell_style);
383 }
384
385 pub fn with_styling(self, styling: Option<Box<ValueStyle>>) -> Self {
387 Self { styling, ..self }
388 }
389
390 pub fn styling_mut(&mut self) -> &mut ValueStyle {
394 self.styling.get_or_insert_default()
395 }
396
397 pub fn font_style(&self) -> Option<&FontStyle> {
399 self.styling
400 .as_ref()
401 .map(|styling| styling.font_style.as_ref())
402 .flatten()
403 }
404
405 pub fn cell_style(&self) -> Option<&CellStyle> {
407 self.styling
408 .as_ref()
409 .map(|styling| styling.cell_style.as_ref())
410 .flatten()
411 }
412
413 pub fn subscripts(&self) -> &[String] {
415 self.styling
416 .as_ref()
417 .map_or(&[], |styling| &styling.subscripts)
418 }
419
420 pub fn footnotes(&self) -> &[Arc<Footnote>] {
422 self.styling
423 .as_ref()
424 .map_or(&[], |styling| &styling.footnotes)
425 }
426
427 pub fn display(&self, options: impl Into<ValueOptions>) -> DisplayValue<'_> {
431 let display = self.inner.display(options);
432 match &self.styling {
433 Some(styling) => display.with_styling(styling),
434 None => display,
435 }
436 }
437
438 pub fn serialize_bare<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
442 where
443 S: Serializer,
444 {
445 BareValue(self).serialize(serializer)
446 }
447}
448
449impl From<&str> for Value {
450 fn from(value: &str) -> Self {
451 Self::new_text(value)
452 }
453}
454
455impl From<String> for Value {
456 fn from(value: String) -> Self {
457 Self::new_text(value)
458 }
459}
460
461impl From<&Variable> for Value {
462 fn from(variable: &Variable) -> Self {
463 Self::new_variable(variable)
464 }
465}
466
467#[derive(Clone, Debug)]
471pub struct DisplayValue<'a> {
472 inner: &'a ValueInner,
473 subscripts: &'a [String],
474 footnotes: &'a [Arc<Footnote>],
475 options: ValueOptions,
476 show_value: bool,
477 show_label: Option<&'a str>,
478}
479
480impl<'a> DisplayValue<'a> {
481 pub fn subscripts(&self) -> impl Iterator<Item = &str> + ExactSizeIterator + Clone {
483 self.subscripts.iter().map(String::as_str)
484 }
485
486 pub fn has_subscripts(&self) -> bool {
488 !self.subscripts.is_empty()
489 }
490
491 pub fn footnotes(&self) -> impl Iterator<Item = impl Display> + Clone {
496 self.footnotes
497 .iter()
498 .filter(|f| f.show)
499 .map(|f| f.display_marker(self.options.clone()))
500 }
501
502 pub fn has_footnotes(&self) -> bool {
507 self.footnotes().next().is_some()
508 }
509
510 pub fn without_suffixes(self) -> Self {
513 Self {
514 subscripts: &[],
515 footnotes: &[],
516 ..self
517 }
518 }
519
520 pub fn without_body(self) -> Self {
523 Self {
524 inner: &ValueInner::Empty,
525 ..self
526 }
527 }
528
529 pub fn markup(&self) -> Option<&Markup> {
531 self.inner.as_markup()
532 }
533
534 pub fn split(self) -> (Self, Self) {
537 (self.clone().without_suffixes(), self.without_body())
538 }
539
540 pub fn with_styling(mut self, styling: &'a ValueStyle) -> Self {
545 self.subscripts = styling.subscripts.as_slice();
546 self.footnotes = styling.footnotes.as_slice();
547 self
548 }
549
550 pub fn with_subscripts(self, subscripts: &'a [String]) -> Self {
552 Self { subscripts, ..self }
553 }
554
555 pub fn with_footnotes(self, footnotes: &'a [Arc<Footnote>]) -> Self {
557 Self { footnotes, ..self }
558 }
559
560 pub fn is_empty(&self) -> bool {
562 self.inner.is_empty() && self.subscripts.is_empty() && self.footnotes.is_empty()
563 }
564
565 pub fn decimal(&self) -> Option<Decimal> {
569 self.inner
570 .as_datum_value()
571 .map(|datum_value| datum_value.decimal())
572 }
573
574 fn small(&self) -> f64 {
575 self.options.small
576 }
577
578 pub fn var_type(&self) -> VarType {
590 if let Some(datum_value) = self.inner.as_datum_value()
591 && datum_value.datum.is_number()
592 && self.show_label.is_none()
593 {
594 VarType::Numeric
595 } else {
596 VarType::String
597 }
598 }
599}
600
601impl Display for DisplayValue<'_> {
602 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
603 match self.inner {
604 ValueInner::Datum(datum_value) => datum_value.display(self, f),
605 ValueInner::Variable(variable_value) => variable_value.display(self, f),
606 ValueInner::Markup(markup) => write!(f, "{markup}"),
607 ValueInner::Text(text_value) => write!(f, "{text_value}"),
608 ValueInner::Template(template_value) => template_value.display(self, f),
609 ValueInner::Empty => Ok(()),
610 }?;
611
612 for (subscript, delimiter) in self.subscripts.iter().zip(once('_').chain(repeat(','))) {
613 write!(f, "{delimiter}{subscript}")?;
614 }
615
616 if !self.footnotes.is_empty() {
617 write!(
618 f,
619 "[{}]",
620 self.footnotes
621 .iter()
622 .map(|f| f.display_marker(&self.options))
623 .format(",")
624 )?;
625 }
626
627 Ok(())
628 }
629}
630
631impl Debug for Value {
632 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
633 let name = match &self.inner {
634 ValueInner::Datum(_) => "Datum",
635 ValueInner::Variable(_) => "Variable",
636 ValueInner::Text(_) => "Text",
637 ValueInner::Markup(_) => "Markup",
638 ValueInner::Template(_) => "Template",
639 ValueInner::Empty => "Empty",
640 };
641 write!(f, "{name}:{:?}", self.display(()).to_string())?;
642 if let Some(markup) = self.inner.as_markup() {
643 write!(f, " (markup: {markup:?})")?;
644 }
645 if let Some(styling) = &self.styling {
646 write!(f, " ({styling:?})")?;
647 }
648 Ok(())
649 }
650}
651
652#[derive(Copy, Clone, Debug, PartialEq)]
658pub enum ValueFormat {
659 Other(Format),
661
662 SmallE(Format),
668}
669
670impl ValueFormat {
671 pub fn inner(&self) -> Format {
673 match self {
674 ValueFormat::Other(format) => *format,
675 ValueFormat::SmallE(format) => *format,
676 }
677 }
678
679 pub fn apply(&self, number: Option<f64>, small: f64) -> Format {
682 if let ValueFormat::SmallE(format) = self
683 && let Some(number) = number
684 && number != 0.0
685 && number.abs() < small
686 {
687 UncheckedFormat::new(Type::E, 40, format.d() as u8).fix()
688 } else {
689 self.inner()
690 }
691 }
692
693 pub fn is_small_e(&self) -> bool {
695 matches!(self, ValueFormat::SmallE(_))
696 }
697}
698
699impl From<Format> for ValueFormat {
700 fn from(format: Format) -> Self {
701 Self::Other(format)
702 }
703}
704
705impl Serialize for ValueFormat {
706 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
707 where
708 S: Serializer,
709 {
710 match self {
711 ValueFormat::Other(format) => format.serialize(serializer),
712 ValueFormat::SmallE(format) => {
713 #[derive(Serialize)]
714 struct SmallE(Format);
715 SmallE(*format).serialize(serializer)
716 }
717 }
718 }
719}
720
721#[derive(Clone, Debug, PartialEq)]
723pub struct DatumValue {
724 pub datum: Datum<WithEncoding<ByteString>>,
726
727 pub format: ValueFormat,
729
730 pub show: Option<Show>,
734
735 pub variable: Option<String>,
737
738 pub value_label: Option<String>,
740}
741
742impl Serialize for DatumValue {
743 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
744 where
745 S: serde::Serializer,
746 {
747 if let ValueFormat::Other(format) = self.format
748 && format.type_() == Type::F
749 && self.variable.is_none()
750 && self.value_label.is_none()
751 {
752 self.datum.serialize(serializer)
753 } else {
754 let mut s = serializer.serialize_map(None)?;
755 s.serialize_entry("datum", &self.datum)?;
756 s.serialize_entry("format", &self.format)?;
757 if let Some(show) = self.show {
758 s.serialize_entry("show", &show)?;
759 }
760 if let Some(variable) = &self.variable {
761 s.serialize_entry("variable", variable)?;
762 }
763 if let Some(value_label) = &self.value_label {
764 s.serialize_entry("value_label", value_label)?;
765 }
766 s.end()
767 }
768 }
769}
770
771impl DatumValue {
772 pub fn new<B>(datum: &Datum<B>) -> Self
774 where
775 B: EncodedString,
776 {
777 Self {
778 datum: datum.cloned(),
779 format: ValueFormat::Other(F8_2),
780 show: None,
781 variable: None,
782 value_label: None,
783 }
784 }
785
786 pub fn new_number(number: Option<f64>) -> Self {
788 Self::new(&Datum::<&str>::Number(number))
789 }
790
791 pub fn with_format(self, format: ValueFormat) -> Self {
793 Self { format, ..self }
794 }
795
796 pub fn display<'a>(
798 &self,
799 display: &DisplayValue<'a>,
800 f: &mut std::fmt::Formatter<'_>,
801 ) -> std::fmt::Result {
802 if display.show_value {
803 match &self.datum {
804 Datum::Number(number) => {
805 let format = self.format.apply(*number, display.small());
806 self.datum
807 .display(format)
808 .with_settings(&display.options.settings)
809 .without_leading_spaces()
810 .fmt(f)?;
811 }
812 Datum::String(s) => {
813 if self.format.inner().type_() == Type::AHex {
814 write!(f, "{}", s.inner.display_hex())?;
815 } else {
816 f.write_str(&s.as_str())?;
817 }
818 }
819 }
820 }
821 if let Some(label) = display.show_label {
822 if display.show_value {
823 f.write_char(' ')?;
824 }
825 f.write_str(label)?;
826 }
827 Ok(())
828 }
829
830 pub fn decimal(&self) -> Decimal {
832 self.datum.display(self.format.inner()).decimal()
833 }
834
835 pub fn serialize_bare<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
838 where
839 S: Serializer,
840 {
841 if let Datum::Number(Some(number)) = &self.datum
842 && let number = *number
843 && number.trunc() == number
844 && number >= -(1i64 << 53) as f64
845 && number <= (1i64 << 53) as f64
846 {
847 Some(number as u64).serialize(serializer)
848 } else {
849 self.datum.serialize(serializer)
850 }
851 }
852}
853
854#[derive(Clone, Debug, Serialize, PartialEq)]
856pub struct VariableValue {
857 pub var_name: String,
859
860 pub variable_label: Option<String>,
862
863 pub show: Option<Show>,
867}
868
869impl VariableValue {
870 fn display(&self, display: &DisplayValue<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
871 if display.show_value {
872 f.write_str(&self.var_name)?;
873 }
874 if let Some(label) = display.show_label {
875 if display.show_value {
876 f.write_char(' ')?;
877 }
878 f.write_str(label)?;
879 }
880 Ok(())
881 }
882}
883
884#[derive(Clone, Debug, PartialEq)]
890pub struct TextValue {
891 pub user_provided: bool,
896
897 pub localized: String,
901
902 pub c: Option<String>,
907
908 pub id: Option<String>,
913}
914
915impl Serialize for TextValue {
916 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
917 where
918 S: serde::Serializer,
919 {
920 if self.user_provided && self.c.is_none() && self.id.is_none() {
921 serializer.serialize_str(&self.localized)
922 } else {
923 let mut s = serializer.serialize_struct(
924 "TextValue",
925 2 + self.c.is_some() as usize + self.id.is_some() as usize,
926 )?;
927 s.serialize_field("user_provided", &self.user_provided)?;
928 s.serialize_field("localized", &self.localized)?;
929 if let Some(c) = &self.c {
930 s.serialize_field("c", &c)?;
931 }
932 if let Some(id) = &self.id {
933 s.serialize_field("id", &id)?;
934 }
935 s.end()
936 }
937 }
938}
939
940impl Display for TextValue {
941 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
942 f.write_str(&self.localized)
943 }
944}
945
946impl TextValue {
947 pub fn localized(&self) -> &str {
949 self.localized.as_str()
950 }
951
952 pub fn c(&self) -> &str {
954 self.c.as_ref().unwrap_or(&self.localized).as_str()
955 }
956
957 pub fn id(&self) -> &str {
959 self.id.as_ref().unwrap_or(&self.localized).as_str()
960 }
961}
962
963#[derive(Clone, Debug, Serialize, PartialEq)]
965pub struct TemplateValue {
966 pub localized: String,
973
974 pub args: Vec<Vec<Value>>,
976
977 pub id: Option<String>,
979}
980
981impl TemplateValue {
982 fn display<'a>(
983 &self,
984 display: &DisplayValue<'a>,
985 f: &mut std::fmt::Formatter<'_>,
986 ) -> std::fmt::Result {
987 #[derive(Copy, Clone, Debug)]
988 struct InnerTemplate<'b> {
989 template: &'b str,
990 escape: char,
991 }
992
993 impl<'b> InnerTemplate<'b> {
994 fn new(template: &'b str, escape: char) -> Self {
995 Self { template, escape }
996 }
997
998 fn extract(input: &'b str, escape: char, end: char) -> (Self, &'b str) {
999 let mut prev = None;
1000 for (index, c) in input.char_indices() {
1001 if c == end && prev != Some('\\') {
1002 return (Self::new(&input[..index], escape), &input[index + 1..]);
1003 }
1004 prev = Some(c);
1005 }
1006 (Self::new(input, escape), "")
1007 }
1008
1009 fn expand(
1010 &self,
1011 options: &ValueOptions,
1012 f: &mut std::fmt::Formatter<'_>,
1013 args: &mut std::slice::Iter<Value>,
1014 ) -> Result<usize, std::fmt::Error> {
1015 let mut iter = self.template.chars();
1016
1017 let mut args_consumed = 1;
1019
1020 while let Some(c) = iter.next() {
1021 match c {
1022 '\\' => {
1023 let c = iter.next().unwrap_or('\\') as char;
1024 let c = if c == 'n' { '\n' } else { c };
1025 write!(f, "{c}")?;
1026 }
1027 c if c == self.escape => {
1028 let (index, rest) = consume_int(iter.as_str());
1029 iter = rest.chars();
1030 if let Some(index) = index.checked_sub(1)
1031 && let Some(arg) = args.as_slice().get(index)
1032 {
1033 args_consumed = args_consumed.max(index + 1);
1034 write!(f, "{}", arg.display(options))?;
1035 }
1036 }
1037 c => write!(f, "{c}")?,
1038 }
1039 }
1040 for _ in 0..args_consumed {
1041 args.next();
1042 }
1043 Ok(args_consumed)
1044 }
1045 }
1046
1047 fn consume_int(input: &str) -> (usize, &str) {
1048 let mut n = 0;
1049 for (index, c) in input.char_indices() {
1050 match c.to_digit(10) {
1051 Some(digit) => n = n * 10 + digit as usize,
1052 None => return (n, &input[index..]),
1053 }
1054 }
1055 (n, "")
1056 }
1057
1058 let mut options = display.options.clone();
1061 options.settings.leading_zero_pct = false;
1062
1063 let mut iter = self.localized.chars();
1064 while let Some(c) = iter.next() {
1065 match c {
1066 '\\' => {
1067 let c = match iter.next() {
1068 None => '\\',
1069 Some('n') => '\n',
1070 Some(c) => c,
1071 };
1072 f.write_char(c)?;
1073 }
1074 '^' => {
1075 let (index, rest) = consume_int(iter.as_str());
1076 if let Some(index) = index.checked_sub(1)
1077 && let Some(arg) = self.args.get(index)
1078 && let Some(arg) = arg.first()
1079 {
1080 write!(f, "{}", arg.display(&options))?;
1081 }
1082 iter = rest.chars();
1083 }
1084 '[' => {
1085 let (a, rest) = InnerTemplate::extract(iter.as_str(), '%', ':');
1086 let (b, rest) = InnerTemplate::extract(rest, '^', ':');
1087 let (c, rest) = InnerTemplate::extract(rest, '$', ']');
1088 let (index, rest) = consume_int(rest);
1089 iter = rest.chars();
1090
1091 let (first, mid, last) = if a.template.is_empty() {
1092 (b, b, b)
1093 } else if c.template.is_empty() {
1094 (a, b, b)
1095 } else {
1096 (a, b, c)
1097 };
1098 if let Some(index) = index.checked_sub(1)
1099 && let Some(args) = self.args.get(index)
1100 {
1101 let mut args = args.iter();
1102 let n = first.expand(&options, f, &mut args)?;
1103 while args.len() > n {
1104 mid.expand(&options, f, &mut args)?;
1105 }
1106 if args.len() > 0 {
1107 last.expand(&options, f, &mut args)?;
1108 }
1109 }
1110 }
1111 c => f.write_char(c)?,
1112 }
1113 }
1114 Ok(())
1115 }
1116}
1117
1118#[derive(Clone, Debug, Default, Serialize, PartialEq)]
1120#[serde(rename_all = "snake_case")]
1121pub enum ValueInner {
1122 Datum(
1124 DatumValue,
1126 ),
1127 Variable(
1129 VariableValue,
1131 ),
1132 Text(
1134 TextValue,
1136 ),
1137 Markup(
1139 Markup,
1141 ),
1142 Template(
1144 TemplateValue,
1146 ),
1147 #[default]
1149 Empty,
1150}
1151
1152impl ValueInner {
1153 pub const fn is_empty(&self) -> bool {
1155 matches!(self, Self::Empty)
1156 }
1157
1158 pub fn with_format(mut self, format: impl Into<ValueFormat>) -> Self {
1161 if let Some(datum_value) = self.as_datum_value_mut() {
1162 datum_value.format = format.into();
1163 }
1164 self
1165 }
1166
1167 pub fn datum(&self) -> Option<&Datum<WithEncoding<ByteString>>> {
1169 self.as_datum_value().map(|d| &d.datum)
1170 }
1171
1172 fn show(&self) -> Option<Show> {
1175 match self {
1176 ValueInner::Datum(DatumValue { show, .. })
1177 | ValueInner::Variable(VariableValue { show, .. }) => *show,
1178 _ => None,
1179 }
1180 }
1181
1182 pub fn label(&self) -> Option<&str> {
1185 self.value_label().or_else(|| self.variable_label())
1186 }
1187
1188 fn value_label(&self) -> Option<&str> {
1190 self.as_datum_value()
1191 .and_then(|d| d.value_label.as_ref().map(String::as_str))
1192 }
1193
1194 fn variable_label(&self) -> Option<&str> {
1196 self.as_variable_value()
1197 .and_then(|d| d.variable_label.as_ref().map(String::as_str))
1198 }
1199
1200 pub fn as_datum_value(&self) -> Option<&DatumValue> {
1203 match self {
1204 ValueInner::Datum(datum) => Some(datum),
1205 _ => None,
1206 }
1207 }
1208
1209 pub fn as_datum_value_mut(&mut self) -> Option<&mut DatumValue> {
1212 match self {
1213 ValueInner::Datum(datum) => Some(datum),
1214 _ => None,
1215 }
1216 }
1217
1218 pub fn as_variable_value(&self) -> Option<&VariableValue> {
1221 match self {
1222 ValueInner::Variable(variable) => Some(variable),
1223 _ => None,
1224 }
1225 }
1226
1227 pub fn as_variable_value_mut(&mut self) -> Option<&mut VariableValue> {
1230 match self {
1231 ValueInner::Variable(variable) => Some(variable),
1232 _ => None,
1233 }
1234 }
1235
1236 fn as_markup(&self) -> Option<&Markup> {
1238 match self {
1239 ValueInner::Markup(markup) => Some(markup),
1240 _ => None,
1241 }
1242 }
1243
1244 pub fn display(&self, options: impl Into<ValueOptions>) -> DisplayValue<'_> {
1247 fn interpret_show(
1248 global_show: impl Fn() -> Show,
1249 table_show: Option<Show>,
1250 value_show: Option<Show>,
1251 label: &str,
1252 ) -> (bool, Option<&str>) {
1253 match value_show.or(table_show).unwrap_or_else(global_show) {
1254 Show::Value => (true, None),
1255 Show::Label => (false, Some(label)),
1256 Show::Both => (true, Some(label)),
1257 }
1258 }
1259
1260 let options = options.into();
1261 let (show_value, show_label) = if let Some(value_label) = self.value_label() {
1262 interpret_show(
1263 || Settings::global().show_values,
1264 options.show_values,
1265 self.show(),
1266 value_label,
1267 )
1268 } else if let Some(variable_label) = self.variable_label() {
1269 interpret_show(
1270 || Settings::global().show_variables,
1271 options.show_variables,
1272 self.show(),
1273 variable_label,
1274 )
1275 } else {
1276 (true, None)
1277 };
1278 DisplayValue {
1279 inner: self,
1280 subscripts: &[],
1281 footnotes: &[],
1282 options,
1283 show_value,
1284 show_label,
1285 }
1286 }
1287
1288 pub fn new_user_text(s: impl Into<String>) -> Self {
1291 let s: String = s.into();
1292 if !s.is_empty() {
1293 Self::Text(TextValue {
1294 user_provided: true,
1295 localized: s,
1296 c: None,
1297 id: None,
1298 })
1299 } else {
1300 Self::Empty
1301 }
1302 }
1303}
1304
1305#[derive(Clone, Debug, Default, PartialEq)]
1310pub struct ValueStyle {
1311 pub cell_style: Option<CellStyle>,
1313
1314 pub font_style: Option<FontStyle>,
1316
1317 pub subscripts: Vec<String>,
1319
1320 pub footnotes: Vec<Arc<Footnote>>,
1322}
1323
1324impl ValueStyle {
1325 pub fn is_empty(&self) -> bool {
1330 self.font_style.is_none()
1331 && self.cell_style.is_none()
1332 && self.subscripts.is_empty()
1333 && self.footnotes.is_empty()
1334 }
1335}
1336
1337#[derive(Clone, Debug)]
1339pub struct ValueOptions {
1340 pub show_values: Option<Show>,
1344
1345 pub show_variables: Option<Show>,
1349
1350 pub small: f64,
1353
1354 pub footnote_marker_type: FootnoteMarkerType,
1356
1357 pub settings: format::Settings,
1359}
1360
1361impl Default for ValueOptions {
1362 fn default() -> Self {
1363 Self {
1364 show_values: None,
1365 show_variables: None,
1366 small: 0.0001,
1367 footnote_marker_type: FootnoteMarkerType::default(),
1368 settings: Settings::global().formats.clone(),
1369 }
1370 }
1371}
1372
1373impl From<()> for ValueOptions {
1374 fn from(_: ()) -> Self {
1375 ValueOptions::default()
1376 }
1377}
1378
1379impl From<&ValueOptions> for ValueOptions {
1380 fn from(value: &ValueOptions) -> Self {
1381 value.clone()
1382 }
1383}