Skip to content

Commit d9fc178

Browse files
authored
Merge pull request #160 from faststats-dev/feat/map-metrics
Add map type metrics
2 parents b3ba3d1 + 12217a4 commit d9fc178

6 files changed

Lines changed: 84 additions & 7 deletions

File tree

core/src/main/java/dev/faststats/core/data/ArrayMetric.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.util.concurrent.Callable;
99

1010
final class ArrayMetric<T> extends SimpleMetric<T[]> {
11-
public ArrayMetric(@SourceId final String id, final Callable<T @Nullable []> callable) throws IllegalArgumentException {
11+
public ArrayMetric(@SourceId final String id, final Callable<? extends T @Nullable []> callable) throws IllegalArgumentException {
1212
super(id, callable);
1313
}
1414

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package dev.faststats.core.data;
2+
3+
import com.google.gson.JsonElement;
4+
import com.google.gson.JsonObject;
5+
import org.jspecify.annotations.Nullable;
6+
7+
import java.util.Map;
8+
import java.util.Optional;
9+
import java.util.concurrent.Callable;
10+
11+
final class MapMetric<T> extends SimpleMetric<Map<String, ? extends T>> {
12+
public MapMetric(@SourceId final String id, final Callable<? extends @Nullable Map<String, ? extends T>> callable) throws IllegalArgumentException {
13+
super(id, callable);
14+
}
15+
16+
@Override
17+
public Optional<JsonElement> getData() throws Exception {
18+
return compute().map(data -> {
19+
final var object = new JsonObject();
20+
data.forEach((key, value) -> {
21+
if (value instanceof final Boolean bool) object.addProperty(key, bool);
22+
else if (value instanceof final Number number) object.addProperty(key, number);
23+
else object.addProperty(key, value.toString());
24+
});
25+
return object;
26+
});
27+
}
28+
}

core/src/main/java/dev/faststats/core/data/Metric.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.jetbrains.annotations.Contract;
55
import org.jspecify.annotations.Nullable;
66

7+
import java.util.Map;
78
import java.util.Optional;
89
import java.util.concurrent.Callable;
910

@@ -33,7 +34,7 @@ public interface Metric<T> {
3334
* @since 0.16.0
3435
*/
3536
@Contract(pure = true)
36-
Optional<T> compute() throws Exception;
37+
Optional<? extends T> compute() throws Exception;
3738

3839
/**
3940
* Get the metric data as a JSON element.
@@ -96,6 +97,54 @@ static Metric<Number[]> numberArray(@SourceId final String id, final Callable<Nu
9697
return new ArrayMetric<>(id, callable);
9798
}
9899

100+
/**
101+
* Create a string map metric.
102+
*
103+
* @param id the source id
104+
* @param callable the metric data callable
105+
* @return the string map metric
106+
* @throws IllegalArgumentException if the source id is invalid
107+
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
108+
* @see #compute()
109+
* @since 0.23.0
110+
*/
111+
@Contract(value = "_, _ -> new", pure = true)
112+
static Metric<Map<String, ? extends String>> stringMap(@SourceId final String id, final Callable<? extends @Nullable Map<String, String>> callable) throws IllegalArgumentException {
113+
return new MapMetric<>(id, callable);
114+
}
115+
116+
/**
117+
* Create a boolean map metric.
118+
*
119+
* @param id the source id
120+
* @param callable the metric data callable
121+
* @return the boolean map metric
122+
* @throws IllegalArgumentException if the source id is invalid
123+
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
124+
* @see #compute()
125+
* @since 0.23.0
126+
*/
127+
@Contract(value = "_, _ -> new", pure = true)
128+
static Metric<Map<String, ? extends Boolean>> booleanMap(@SourceId final String id, final Callable<? extends @Nullable Map<String, Boolean>> callable) throws IllegalArgumentException {
129+
return new MapMetric<>(id, callable);
130+
}
131+
132+
/**
133+
* Create a number map metric.
134+
*
135+
* @param id the source id
136+
* @param callable the metric data callable
137+
* @return the number map metric
138+
* @throws IllegalArgumentException if the source id is invalid
139+
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
140+
* @see #compute()
141+
* @since 0.23.0
142+
*/
143+
@Contract(value = "_, _ -> new", pure = true)
144+
static Metric<Map<String, ? extends Number>> numberMap(@SourceId final String id, final Callable<? extends @Nullable Map<String, ? extends Number>> callable) throws IllegalArgumentException {
145+
return new MapMetric<>(id, callable);
146+
}
147+
99148
/**
100149
* Create a metric for a boolean value.
101150
*

core/src/main/java/dev/faststats/core/data/SimpleMetric.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
abstract class SimpleMetric<T> implements Metric<T> {
1010
private final @SourceId String id;
11-
private final Callable<@Nullable T> callable;
11+
private final Callable<? extends @Nullable T> callable;
1212

13-
public SimpleMetric(@SourceId final String id, final Callable<@Nullable T> callable) throws IllegalArgumentException {
13+
public SimpleMetric(@SourceId final String id, final Callable<? extends @Nullable T> callable) throws IllegalArgumentException {
1414
if (!id.matches(SourceId.PATTERN)) {
1515
throw new IllegalArgumentException("Invalid source id '" + id + "', must match '" + SourceId.PATTERN + "'");
1616
}
@@ -28,7 +28,7 @@ public final Optional<T> compute() throws Exception {
2828
}
2929

3030
@Override
31-
public boolean equals(final Object o) {
31+
public boolean equals(@Nullable final Object o) {
3232
if (o == null || getClass() != o.getClass()) return false;
3333
final SimpleMetric<?> that = (SimpleMetric<?>) o;
3434
return Objects.equals(id, that.id);

core/src/main/java/dev/faststats/core/data/SingleValueMetric.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.util.concurrent.Callable;
99

1010
final class SingleValueMetric<T> extends SimpleMetric<T> {
11-
public SingleValueMetric(@SourceId final String id, final Callable<@Nullable T> callable) throws IllegalArgumentException {
11+
public SingleValueMetric(@SourceId final String id, final Callable<? extends @Nullable T> callable) throws IllegalArgumentException {
1212
super(id, callable);
1313
}
1414

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=0.22.1
1+
version=0.23.0

0 commit comments

Comments
 (0)