Skip to content

Commit 57a90fe

Browse files
committed
feat: SimpleMetadata
1 parent 3ea2a58 commit 57a90fe

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package org.variantsync.diffdetective.analysis;
2+
3+
import org.variantsync.diffdetective.metadata.Metadata;
4+
import org.variantsync.functjonal.category.InplaceSemigroup;
5+
import org.variantsync.functjonal.error.NotImplementedException;
6+
7+
import java.util.LinkedHashMap;
8+
import java.util.function.BiFunction;
9+
import java.util.function.Function;
10+
11+
/**
12+
* Default implementation for metadata that just wraps a single value.
13+
* TODO: Move this implementation to Functjonal.
14+
* @param <V> The type of the value to store (e.g., Integer when we want to count something).
15+
* @param <Derived> The type of the subclass that derives this class.
16+
* @author Paul Bittner
17+
*/
18+
public abstract class SimpleMetadata<V, Derived extends SimpleMetadata<V, Derived>> implements Metadata<Derived> {
19+
public V value;
20+
private final String valueName;
21+
private final BiFunction<V, V, V> compose;
22+
private final Function<String, V> parser;
23+
24+
/**
25+
* Create simple metadata with the given default value, name, and composition operator.
26+
* Creating simple metadata this way, will not implement the parse method, which makes reading
27+
* a corresponding value from a string crash.
28+
* If you need parsing, use {@link #SimpleMetadata(Object, String, BiFunction, Function)}
29+
* @param initialValue initial value of the stored value (e.g., 0 for integer)
30+
* @param valueName the name this value should have
31+
* @param compose A binary function which composes two values (e.g., + for integer).
32+
*/
33+
public SimpleMetadata(
34+
V initialValue,
35+
String valueName,
36+
BiFunction<V, V, V> compose
37+
) {
38+
this(initialValue, valueName, compose, (s) -> {throw new NotImplementedException();});
39+
}
40+
41+
/**
42+
* Create simple metadata with the given default value, name, and composition operator.
43+
* @param initialValue initial value of the stored value (e.g., 0 for integer)
44+
* @param valueName the name this value should have
45+
* @param compose A binary function which composes two values (e.g., + for integer).
46+
* @param parse A method to parse the corresponding value from a string that contains just the string representation
47+
* of the value. This should be inverse to {@code V::toString }.
48+
*/
49+
protected SimpleMetadata(
50+
V initialValue,
51+
String valueName,
52+
BiFunction<V, V, V> compose,
53+
Function<String, V> parse
54+
) {
55+
this.value = initialValue;
56+
this.valueName = valueName;
57+
this.compose = compose;
58+
this.parser = parse;
59+
}
60+
61+
62+
@Override
63+
public LinkedHashMap<String, ?> snapshot() {
64+
final LinkedHashMap<String, Object> snap = new LinkedHashMap<>(1);
65+
snap.put(valueName, value);
66+
return snap;
67+
}
68+
69+
@Override
70+
public void setFromSnapshot(LinkedHashMap<String, String> snapshot) {
71+
this.value = parser.apply(snapshot.get(valueName));
72+
}
73+
74+
@Override
75+
public InplaceSemigroup<Derived> semigroup() {
76+
return (a, b) -> {
77+
a.value = compose.apply(a.value, b.value);
78+
};
79+
}
80+
}

0 commit comments

Comments
 (0)