word_tally/options/
serialization.rs

1//! Serialization format options and settings.
2//!
3//! Word tallies can be serialized in three formats:
4//! - **Text**: Customizable delimiters for field/value and entry separation
5//! - **JSON**: Machine-readable structured format
6//! - **CSV**: Comma-separated values for spreadsheet compatibility
7//!
8//! # Delimiter Configuration
9//!
10//! Delimiters are only applicable to text format. When using JSON or CSV formats
11//! with the CLI, delimiter flags (`--field-delimiter`, `--entry-delimiter`) will
12//! cause an error. For the library API, delimiters are encapsulated within the
13//! `Text` variant and cannot be mistakenly applied to other formats.
14//!
15//! # Examples
16//!
17//! ```
18//! use word_tally::{Delimiters, Serialization};
19//!
20//! // Text format with custom delimiters
21//! let text_format = Serialization::Text(
22//!     Delimiters::default()
23//!         .with_field_delimiter("::")
24//!         .with_entry_delimiter(";"),
25//! );
26//!
27//! // JSON format (no delimiter configuration)
28//! let json_format = Serialization::Json;
29//!
30//! // CSV format (uses standard CSV delimiters)
31//! let csv_format = Serialization::Csv;
32//! ```
33
34use core::fmt::{self, Display, Formatter};
35
36use serde::{Deserialize, Serialize};
37
38use crate::options::delimiters::Delimiters;
39
40/// Serialization format options.
41#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub enum Serialization {
44    /// Plain text output with configurable delimiters.
45    Text(Delimiters),
46    /// JSON output.
47    Json,
48    /// CSV output.
49    Csv,
50}
51
52impl Serialization {
53    /// Get the field delimiter formatted for display, or "n/a" if not text format.
54    #[must_use]
55    pub fn field_delimiter_display(&self) -> String {
56        match self {
57            Self::Text(delimiters) => delimiters.field_display(),
58            _ => "n/a".to_string(),
59        }
60    }
61
62    /// Get the entry delimiter formatted for display, or "n/a" if not text format.
63    #[must_use]
64    pub fn entry_delimiter_display(&self) -> String {
65        match self {
66            Self::Text(delimiters) => delimiters.entry_display(),
67            _ => "n/a".to_string(),
68        }
69    }
70}
71
72impl Default for Serialization {
73    fn default() -> Self {
74        Self::Text(Delimiters::default())
75    }
76}
77
78impl Display for Serialization {
79    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
80        match self {
81            Self::Text(delimiters) => write!(f, "text[{delimiters}]"),
82            Self::Json => write!(f, "json"),
83            Self::Csv => write!(f, "csv"),
84        }
85    }
86}