Skip to content

Commit 9d68aa8

Browse files
committed
refactor(data): Shrink the size of Data
1 parent 5487171 commit 9d68aa8

6 files changed

Lines changed: 116 additions & 90 deletions

File tree

crates/snapbox/src/assert/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,26 +113,26 @@ impl Assert {
113113
mut actual: crate::Data,
114114
mut expected: crate::Data,
115115
) -> (crate::Data, crate::Data) {
116-
if expected.filters.is_newlines_set() {
116+
if expected.inner.filters.is_newlines_set() {
117117
expected = FilterNewlines.filter(expected);
118118
}
119119

120120
// On `expected` being an error, make a best guess
121121
actual = actual.coerce_to(expected.against_format());
122122
actual = actual.coerce_to(expected.intended_format());
123123

124-
if self.normalize_paths && expected.filters.is_paths_set() {
124+
if self.normalize_paths && expected.inner.filters.is_paths_set() {
125125
actual = FilterPaths.filter(actual);
126126
}
127-
if expected.filters.is_newlines_set() {
127+
if expected.inner.filters.is_newlines_set() {
128128
actual = FilterNewlines.filter(actual);
129129
}
130130

131131
let mut normalize = NormalizeToExpected::new();
132-
if expected.filters.is_redaction_set() {
132+
if expected.inner.filters.is_redaction_set() {
133133
normalize = normalize.redact_with(&self.substitutions);
134134
}
135-
if expected.filters.is_unordered_set() {
135+
if expected.inner.filters.is_unordered_set() {
136136
normalize = normalize.unordered();
137137
}
138138
actual = normalize.normalize(actual, &expected);

crates/snapbox/src/data/mod.rs

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,11 @@ macro_rules! str {
379379
/// This provides conveniences for tracking the intended format (binary vs text).
380380
#[derive(Clone, Debug)]
381381
pub struct Data {
382+
pub(crate) inner: Box<DataInner>,
383+
}
384+
385+
#[derive(Clone, Debug)]
386+
pub(crate) struct DataInner {
382387
pub(crate) value: DataValue,
383388
pub(crate) source: Option<DataSource>,
384389
pub(crate) filters: FilterSet,
@@ -451,13 +456,13 @@ impl Data {
451456

452457
/// Remove default [`filters`][crate::filter] from this `expected` result
453458
pub fn raw(mut self) -> Self {
454-
self.filters = FilterSet::empty().newlines();
459+
self.inner.filters = FilterSet::empty().newlines();
455460
self
456461
}
457462

458463
/// Treat lines and json arrays as unordered
459464
pub fn unordered(mut self) -> Self {
460-
self.filters = self.filters.unordered();
465+
self.inner.filters = self.inner.filters.unordered();
461466
self
462467
}
463468
}
@@ -468,14 +473,16 @@ impl Data {
468473
impl Data {
469474
pub(crate) fn with_value(value: DataValue) -> Self {
470475
Self {
471-
value,
472-
source: None,
473-
filters: FilterSet::new(),
476+
inner: Box::new(DataInner {
477+
value,
478+
source: None,
479+
filters: FilterSet::new(),
480+
}),
474481
}
475482
}
476483

477484
fn with_source(mut self, source: impl Into<DataSource>) -> Self {
478-
self.source = Some(source.into());
485+
self.inner.source = Some(source.into());
479486
self
480487
}
481488

@@ -536,7 +543,7 @@ impl Data {
536543
///
537544
/// Note: this will not inspect binary data for being a valid `String`.
538545
pub fn render(&self) -> Option<String> {
539-
match &self.value {
546+
match &self.inner.value {
540547
DataValue::Error(_) => None,
541548
DataValue::Binary(_) => None,
542549
DataValue::Text(data) => Some(data.to_owned()),
@@ -550,7 +557,7 @@ impl Data {
550557
}
551558

552559
pub fn to_bytes(&self) -> crate::assert::Result<Vec<u8>> {
553-
match &self.value {
560+
match &self.inner.value {
554561
DataValue::Error(err) => Err(err.error.clone()),
555562
DataValue::Binary(data) => Ok(data.clone()),
556563
DataValue::Text(data) => Ok(data.clone().into_bytes()),
@@ -567,8 +574,8 @@ impl Data {
567574
///
568575
/// This is generally used for `expected` data
569576
pub fn is(self, format: DataFormat) -> Self {
570-
let filters = self.filters;
571-
let source = self.source.clone();
577+
let filters = self.inner.filters;
578+
let source = self.inner.source.clone();
572579
match self.try_is(format) {
573580
Ok(new) => new,
574581
Err(err) => {
@@ -577,19 +584,21 @@ impl Data {
577584
intended: format,
578585
});
579586
Self {
580-
value,
581-
source,
582-
filters,
587+
inner: Box::new(DataInner {
588+
value,
589+
source,
590+
filters,
591+
}),
583592
}
584593
}
585594
}
586595
}
587596

588597
fn try_is(self, format: DataFormat) -> crate::assert::Result<Self> {
589598
let original = self.format();
590-
let source = self.source;
591-
let filters = self.filters;
592-
let value = match (self.value, format) {
599+
let source = self.inner.source;
600+
let filters = self.inner.filters;
601+
let value = match (self.inner.value, format) {
593602
(DataValue::Error(inner), _) => DataValue::Error(inner),
594603
(DataValue::Binary(inner), DataFormat::Binary) => DataValue::Binary(inner),
595604
(DataValue::Text(inner), DataFormat::Text) => DataValue::Text(inner),
@@ -601,7 +610,7 @@ impl Data {
601610
(DataValue::TermSvg(inner), DataFormat::TermSvg) => DataValue::TermSvg(inner),
602611
(DataValue::Binary(inner), _) => {
603612
let value = String::from_utf8(inner).map_err(|_err| "invalid UTF-8".to_owned())?;
604-
Self::text(value).try_is(format)?.value
613+
Self::text(value).try_is(format)?.inner.value
605614
}
606615
#[cfg(feature = "json")]
607616
(DataValue::Text(inner), DataFormat::Json) => {
@@ -632,9 +641,11 @@ impl Data {
632641
(_, _) => return Err(format!("cannot convert {original:?} to {format:?}").into()),
633642
};
634643
Ok(Self {
635-
value,
636-
source,
637-
filters,
644+
inner: Box::new(DataInner {
645+
value,
646+
source,
647+
filters,
648+
}),
638649
})
639650
}
640651

@@ -657,17 +668,17 @@ impl Data {
657668
/// # }
658669
/// ```
659670
fn against(mut self, format: DataFormat) -> Data {
660-
self.filters = self.filters.against(format);
671+
self.inner.filters = self.inner.filters.against(format);
661672
self
662673
}
663674

664675
/// Convert `Self` to [`format`][DataFormat] if possible
665676
///
666677
/// This is generally used on `actual` data to make it match `expected`
667678
pub fn coerce_to(self, format: DataFormat) -> Self {
668-
let source = self.source;
669-
let filters = self.filters;
670-
let value = match (self.value, format) {
679+
let source = self.inner.source;
680+
let filters = self.inner.filters;
681+
let value = match (self.inner.value, format) {
671682
(DataValue::Error(inner), _) => DataValue::Error(inner),
672683
(value, DataFormat::Error) => value,
673684
(DataValue::Binary(inner), DataFormat::Binary) => DataValue::Binary(inner),
@@ -696,7 +707,7 @@ impl Data {
696707
} else {
697708
coerced
698709
};
699-
coerced.value
710+
coerced.inner.value
700711
}
701712
Err(err) => {
702713
let bin = err.into_bytes();
@@ -736,7 +747,7 @@ impl Data {
736747
if let Some(str) = remake.render() {
737748
DataValue::Text(str)
738749
} else {
739-
remake.value
750+
remake.inner.value
740751
}
741752
}
742753
// reachable if more than one structured data format is enabled
@@ -753,20 +764,22 @@ impl Data {
753764
(value, DataFormat::TermSvg) => value,
754765
};
755766
Self {
756-
value,
757-
source,
758-
filters,
767+
inner: Box::new(DataInner {
768+
value,
769+
source,
770+
filters,
771+
}),
759772
}
760773
}
761774

762775
/// Location the data came from
763776
pub fn source(&self) -> Option<&DataSource> {
764-
self.source.as_ref()
777+
self.inner.source.as_ref()
765778
}
766779

767780
/// Outputs the current `DataFormat` of the underlying data
768781
pub fn format(&self) -> DataFormat {
769-
match &self.value {
782+
match &self.inner.value {
770783
DataValue::Error(_) => DataFormat::Error,
771784
DataValue::Binary(_) => DataFormat::Binary,
772785
DataValue::Text(_) => DataFormat::Text,
@@ -780,7 +793,7 @@ impl Data {
780793
}
781794

782795
pub(crate) fn intended_format(&self) -> DataFormat {
783-
match &self.value {
796+
match &self.inner.value {
784797
DataValue::Error(DataError { intended, .. }) => *intended,
785798
DataValue::Binary(_) => DataFormat::Binary,
786799
DataValue::Text(_) => DataFormat::Text,
@@ -794,13 +807,14 @@ impl Data {
794807
}
795808

796809
pub(crate) fn against_format(&self) -> DataFormat {
797-
self.filters
810+
self.inner
811+
.filters
798812
.get_against()
799813
.unwrap_or_else(|| self.intended_format())
800814
}
801815

802816
pub(crate) fn relevant(&self) -> Option<&str> {
803-
match &self.value {
817+
match &self.inner.value {
804818
DataValue::Error(_) => None,
805819
DataValue::Binary(_) => None,
806820
DataValue::Text(_) => None,
@@ -816,7 +830,7 @@ impl Data {
816830

817831
impl std::fmt::Display for Data {
818832
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
819-
match &self.value {
833+
match &self.inner.value {
820834
DataValue::Error(data) => data.fmt(f),
821835
DataValue::Binary(data) => String::from_utf8_lossy(data).fmt(f),
822836
DataValue::Text(data) => data.fmt(f),
@@ -838,7 +852,7 @@ impl std::fmt::Display for Data {
838852

839853
impl PartialEq for Data {
840854
fn eq(&self, other: &Data) -> bool {
841-
match (&self.value, &other.value) {
855+
match (&self.inner.value, &other.inner.value) {
842856
(DataValue::Error(left), DataValue::Error(right)) => left == right,
843857
(DataValue::Binary(left), DataValue::Binary(right)) => left == right,
844858
(DataValue::Text(left), DataValue::Text(right)) => left == right,

crates/snapbox/src/filter/mod.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ pub trait Filter {
2727
pub struct FilterNewlines;
2828
impl Filter for FilterNewlines {
2929
fn filter(&self, data: Data) -> Data {
30-
let source = data.source;
31-
let filters = data.filters;
32-
let inner = match data.value {
30+
let source = data.inner.source;
31+
let filters = data.inner.filters;
32+
let inner = match data.inner.value {
3333
DataValue::Error(err) => DataValue::Error(err),
3434
DataValue::Binary(bin) => DataValue::Binary(bin),
3535
DataValue::Text(text) => {
@@ -55,9 +55,11 @@ impl Filter for FilterNewlines {
5555
}
5656
};
5757
Data {
58-
value: inner,
59-
source,
60-
filters,
58+
inner: Box::new(crate::data::DataInner {
59+
value: inner,
60+
source,
61+
filters,
62+
}),
6163
}
6264
}
6365
}
@@ -74,9 +76,9 @@ fn normalize_lines_chars(data: impl Iterator<Item = char>) -> impl Iterator<Item
7476
pub struct FilterPaths;
7577
impl Filter for FilterPaths {
7678
fn filter(&self, data: Data) -> Data {
77-
let source = data.source;
78-
let filters = data.filters;
79-
let inner = match data.value {
79+
let source = data.inner.source;
80+
let filters = data.inner.filters;
81+
let inner = match data.inner.value {
8082
DataValue::Error(err) => DataValue::Error(err),
8183
DataValue::Binary(bin) => DataValue::Binary(bin),
8284
DataValue::Text(text) => {
@@ -102,9 +104,11 @@ impl Filter for FilterPaths {
102104
}
103105
};
104106
Data {
105-
value: inner,
106-
source,
107-
filters,
107+
inner: Box::new(crate::data::DataInner {
108+
value: inner,
109+
source,
110+
filters,
111+
}),
108112
}
109113
}
110114
}
@@ -128,9 +132,9 @@ struct NormalizeRedactions<'r> {
128132
}
129133
impl Filter for NormalizeRedactions<'_> {
130134
fn filter(&self, data: Data) -> Data {
131-
let source = data.source;
132-
let filters = data.filters;
133-
let inner = match data.value {
135+
let source = data.inner.source;
136+
let filters = data.inner.filters;
137+
let inner = match data.inner.value {
134138
DataValue::Error(err) => DataValue::Error(err),
135139
DataValue::Binary(bin) => DataValue::Binary(bin),
136140
DataValue::Text(text) => {
@@ -156,9 +160,11 @@ impl Filter for NormalizeRedactions<'_> {
156160
}
157161
};
158162
Data {
159-
value: inner,
160-
source,
161-
filters,
163+
inner: Box::new(crate::data::DataInner {
164+
value: inner,
165+
source,
166+
filters,
167+
}),
162168
}
163169
}
164170
}

0 commit comments

Comments
 (0)