Skip to content

Commit 9dbbc9f

Browse files
committed
Fix marge and patch to correctly set/unset repeats
1 parent bc09a8b commit 9dbbc9f

3 files changed

Lines changed: 33 additions & 7 deletions

File tree

src/types/diff/struct_mergeable.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use pyo3::{Bound, PyResult, Python};
22
use pyo3::prelude::PyDictMethods;
33
use pyo3::types::PyDict;
4-
4+
use crate::retrievers::retriever::RetState;
55
use crate::types::base_struct::BaseStruct;
66
use crate::types::diff::diff::{Diff, Diffable, IDiff};
77
use crate::types::diff::merge::{Conflict, Mergeable};
@@ -24,13 +24,35 @@ impl Mergeable<ParseableType> for StructMergeable<'_, '_> {
2424
_off: isize
2525
) -> isize {
2626
let mut inner = self.1.inner_mut();
27-
let data = &mut inner.data;
27+
let (data, repeats, _) = inner.split();
2828
match change {
2929
Diff::None => _off,
3030
Diff::Inserted(_val) | Diff::Deleted(_val) => {
3131
unreachable!("BFP Internal Error: merge called on structs of different versions")
3232
}
3333
Diff::Changed(val) => {
34+
let retriever = &self.0.retrievers()[idx];
35+
match retriever.state(repeats) {
36+
RetState::Value | RetState::NoneValue if val.is_none() => {
37+
repeats[idx] = Some(-1);
38+
}
39+
RetState::Value | RetState::NoneValue => {
40+
repeats[idx] = None;
41+
}
42+
RetState::List | RetState::NoneList if val.is_none() => {
43+
repeats[idx] = Some(-2);
44+
}
45+
RetState::List | RetState::NoneList => {
46+
let repeat = retriever.repeat(repeats);
47+
let len = val.try_len()
48+
.expect("non-null value coming from another struct must be of the correct type") as isize;
49+
if repeat == -2 {
50+
repeats[idx] = Some(len);
51+
} else if repeats[idx].is_none() && repeat != len {
52+
unreachable!("BFP Internal Error: Non-null value coming from another struct must be of the correct type")
53+
}
54+
}
55+
};
3456
data[idx] = Some(val);
3557
_off
3658
}

src/types/parseable_type.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ pub enum ParseableType {
4949
}
5050

5151
impl ParseableType {
52+
pub fn is_none(&self) -> bool {
53+
matches!(self, ParseableType::None)
54+
}
55+
5256
pub fn is_ls_of(&self, bfp_type: &BfpType) -> bool {
5357
match self {
5458
ParseableType::Array(val) => {
@@ -310,8 +314,8 @@ impl Diffable<ParseableType> for ParseableType {
310314
fn diff(&self, other: &ParseableType) -> Diff<ParseableType> {
311315
match (self, other) {
312316
(ParseableType::None, ParseableType::None) => Diff::None,
313-
(ParseableType::None, _) => Diff::Inserted(other.clone()),
314-
(_, ParseableType::None) => Diff::Deleted(other.clone()),
317+
(ParseableType::None, _) => Diff::Changed(other.clone()),
318+
(_, ParseableType::None) => Diff::Changed(other.clone()),
315319

316320
(ParseableType::UInt8(v1), ParseableType::UInt8(v2)) => if v1 == v2 { Diff::None } else { Diff::Changed(other.clone()) },
317321
(ParseableType::UInt16(v1), ParseableType::UInt16(v2)) => if v1 == v2 { Diff::None } else { Diff::Changed(other.clone()) },

stubs/bfp_rs/combinators/if_builder.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class IfBuilder:
110110
"""
111111

112112

113-
def if_(target: Retriever | int | Get) -> IfBuilder:
113+
def if_(*target: Retriever) -> IfBuilder:
114114
"""
115115
Select this value for a comparison
116116
@@ -123,7 +123,7 @@ def if_(target: Retriever | int | Get) -> IfBuilder:
123123
"""
124124

125125

126-
def if_not(target: Retriever | int | Get) -> IfBuilder:
126+
def if_not(*target: Retriever) -> IfBuilder:
127127
"""
128128
Select this value for a comparison with the result inverted
129129
@@ -160,7 +160,7 @@ def if_not_key(key: str) -> IfBuilder:
160160
"""
161161

162162

163-
def if_len(target: Retriever | int | Get) -> IfBuilder:
163+
def if_len(*target: Retriever) -> IfBuilder:
164164
"""
165165
Select this value and use its length for a comparison
166166

0 commit comments

Comments
 (0)