Skip to content

Commit 9284396

Browse files
committed
Fix wrapping logic to work like NbtOps
This is annoying
1 parent 1998c5b commit 9284396

2 files changed

Lines changed: 66 additions & 7 deletions

File tree

dfu/src/main/java/org/enginehub/linbus/dfu/LinOps.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,26 @@ private static void addHomogenized(
462462
return;
463463
}
464464
for (LinTag<?> element : elements) {
465-
builder.add(element instanceof LinCompoundTag existing ? existing : wrapElement(element));
465+
builder.add(wrapElementIfNeeded(element));
466466
}
467467
}
468468

469+
private static LinCompoundTag wrapElementIfNeeded(LinTag<?> element) {
470+
// If the element is a compound that isn't already wrapper-looking, we can use it as-is.
471+
// Otherwise, we need to wrap it again to preserve the value when unwrapped later.
472+
if (element instanceof LinCompoundTag compound && unwrapOrNull(compound) == null) {
473+
return compound;
474+
}
475+
return LinCompoundTag.of(Map.of("", element));
476+
}
477+
478+
private static @Nullable LinTag<?> unwrapOrNull(LinCompoundTag compound) {
479+
if (compound.value().size() == 1) {
480+
return compound.value().get("");
481+
}
482+
return null;
483+
}
484+
469485
/**
470486
* {@return the shared type of {@code elements}, or the compound type if they are heterogeneous}
471487
*
@@ -510,13 +526,9 @@ private static List<LinTag<?>> unwrapStoredList(LinListTag<?> list) {
510526
return result;
511527
}
512528

513-
private static LinCompoundTag wrapElement(LinTag<?> element) {
514-
return LinCompoundTag.of(Map.of("", element));
515-
}
516-
517529
private static LinTag<?> tryUnwrap(LinTag<?> element) {
518-
if (element instanceof LinCompoundTag compound && compound.value().size() == 1) {
519-
LinTag<?> unwrapped = compound.value().get("");
530+
if (element instanceof LinCompoundTag compound) {
531+
LinTag<?> unwrapped = unwrapOrNull(compound);
520532
if (unwrapped != null) {
521533
return unwrapped;
522534
}

dfu/src/test/java/org/enginehub/linbus/dfu/LinOpsListTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,39 @@ void createListWrapsOnlyNonCompoundElementsWhenMixedWithCompound() {
116116
assertThat(OPS.getStream(list)).hasStreamResultThat().containsExactly(a, LinIntTag.of(2)).inOrder();
117117
}
118118

119+
@Test
120+
@NbtOpsBehavior
121+
void createListWrapsWrapperShapedCompoundElements() {
122+
LinCompoundTag wrapperShaped = wrap(LinIntTag.of(1));
123+
LinCompoundTag other = LinCompoundTag.builder().putInt("a", 1).build();
124+
LinTag<?> list = OPS.createList(Stream.of(wrapperShaped, other));
125+
assertThat(list)
126+
.isEqualTo(LinListTag.of(LinTagType.compoundTag(), List.of(wrap(wrapperShaped), other)));
127+
assertThat(OPS.getStream(list))
128+
.hasStreamResultThat().containsExactly(wrapperShaped, other).inOrder();
129+
}
130+
131+
@Test
132+
@NbtOpsBehavior
133+
void createListWrapsWrapperShapedCompoundElementsAlone() {
134+
LinCompoundTag wrapperShaped = wrap(LinIntTag.of(1));
135+
LinTag<?> list = OPS.createList(Stream.of(wrapperShaped));
136+
assertThat(list)
137+
.isEqualTo(LinListTag.of(LinTagType.compoundTag(), List.of(wrap(wrapperShaped))));
138+
assertThat(OPS.getStream(list))
139+
.hasStreamResultThat().containsExactly(wrapperShaped).inOrder();
140+
}
141+
142+
@Test
143+
@NbtOpsBehavior
144+
void createListOfOnlyWrapperShapedCompoundsRoundTrips() {
145+
LinCompoundTag a = wrap(LinIntTag.of(1));
146+
LinCompoundTag b = wrap(LinStringTag.of("x"));
147+
LinTag<?> list = OPS.createList(Stream.of(a, b));
148+
assertThat(list).isEqualTo(LinListTag.of(LinTagType.compoundTag(), List.of(wrap(a), wrap(b))));
149+
assertThat(OPS.getStream(list)).hasStreamResultThat().containsExactly(a, b).inOrder();
150+
}
151+
119152
@Test
120153
void mergeToListOntoEndTakesElementType() {
121154
assertThat(OPS.mergeToList(LinEndTag.instance(), LinIntTag.of(1)))
@@ -157,6 +190,20 @@ void mergeToListGrowsWrappedList() {
157190
)));
158191
}
159192

193+
@Test
194+
@NbtOpsBehavior
195+
void mergeToListWrapsWrapperShapedCompound() {
196+
LinCompoundTag wrapperShaped = wrap(LinIntTag.of(2));
197+
LinTag<?> list = OPS.mergeToList(
198+
LinListTag.of(LinTagType.intTag(), List.of(LinIntTag.of(1))), wrapperShaped
199+
).result().orElseThrow();
200+
assertThat(list).isEqualTo(LinListTag.of(LinTagType.compoundTag(), List.of(
201+
wrap(LinIntTag.of(1)), wrap(wrapperShaped)
202+
)));
203+
assertThat(OPS.getStream(list))
204+
.hasStreamResultThat().containsExactly(LinIntTag.of(1), wrapperShaped).inOrder();
205+
}
206+
160207
@Test
161208
void mergeToListAppendsSeveralValues() {
162209
assertThat(OPS.mergeToList(

0 commit comments

Comments
 (0)