Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package dev.faststats.example;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import dev.faststats.data.Metric;

public final class MetricTypesExample {
Expand All @@ -11,4 +14,17 @@ public final class MetricTypesExample {
// Array metrics
public static final Metric<String[]> INSTALLED_PLUGINS = Metric.stringArray("installed_plugins", () -> new String[]{"WorldEdit", "Essentials"});
public static final Metric<String[]> WORLDS = Metric.stringArray("worlds", () -> new String[]{"city", "farmworld", "farmworld_nether", "famrworld_end"});

// Json metrics
public static final Metric<JsonObject> JSON_OBJECT = Metric.object("nested_example", () -> {
var object = new JsonObject();
object.addProperty("scope", "example");
return object;
});
public static final Metric<JsonArray> JSON_ARRAY = Metric.array("examples", () -> {
var array = new JsonArray();
array.add("example");
return array;
});
public static final Metric<JsonPrimitive> JSON_NUMBER = Metric.primitive("example", () -> new JsonPrimitive("example"));
}
7 changes: 5 additions & 2 deletions core/src/main/java/dev/faststats/SimpleMetrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ private void appendInternalData(final JsonObject metrics) {
private void appendCustomData(final JsonObject metrics) {
this.metrics.forEach(metric -> {
try {
if (metrics.has(metric.getId()))
if (metrics.has(metric.getId())) {
logger.warn("Skipped duplicated metrics entry: %s", metric.getId());
else metric.getData().ifPresent(element -> metrics.add(metric.getId(), element));
} else metric.getData().ifPresent(element -> {
if (!element.isJsonNull()) metrics.add(metric.getId(), element);
else logger.warn("Ignored illegal null entry in metric: %s", metric.getId());
});
} catch (final Throwable t) {
logger.error("Failed to append custom metric data: %s", t, metric.getId());
context.errorTrackerService().ifPresent(service -> service.globalErrorTracker().trackError(t));
Expand Down
27 changes: 0 additions & 27 deletions core/src/main/java/dev/faststats/data/ArrayMetric.java

This file was deleted.

28 changes: 0 additions & 28 deletions core/src/main/java/dev/faststats/data/MapMetric.java

This file was deleted.

101 changes: 79 additions & 22 deletions core/src/main/java/dev/faststats/data/Metric.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package dev.faststats.data;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.Nullable;

Expand Down Expand Up @@ -31,24 +35,77 @@ public interface Metric<T> {
* @return an optional containing the metric data
* @throws Exception if unable to compute the metric data
* @implSpec The implementation must be thread-safe and pure (i.e. not modify any shared state).
* @see #getData()
* @since 0.24.0
* @deprecated This method only adds unnecessary mental overhead. Use {@link #getData()} instead.
*/
@Contract(pure = true)
Optional<? extends T> compute() throws Exception;
@ApiStatus.OverrideOnly
@Deprecated(since = "0.28.0", forRemoval = true)
default Optional<? extends T> compute() throws Exception {
return Optional.empty();
}

/**
* Get the metric data as a JSON element.
*
* @return an optional containing the metric data as {@link JsonElement}
* @throws Exception if unable to get the metric data
* @implSpec The implementation must call {@link #compute()} to get the metric data
* and follow the same thread-safety and pureness requirements.
* @see #compute()
* @implSpec The implementation must be thread-safe and pure (i.e. not modify any shared state).
* @since 0.24.0
*/
@Contract(pure = true)
@ApiStatus.OverrideOnly
Optional<JsonElement> getData() throws Exception;

/**
* Create a JsonObject metric.
*
* @param id the source id
* @param callable the metric data callable
* @return the JsonObject metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #getData()
* @since 0.28.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<JsonObject> object(@SourceId final String id, final Callable<@Nullable JsonObject> callable) throws IllegalArgumentException {
return new SimpleMetric.Json<>(id, callable);
}

/**
* Create a JsonArray metric.
*
* @param id the source id
* @param callable the metric data callable
* @return the JsonArray metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #getData()
* @since 0.28.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<JsonArray> array(@SourceId final String id, final Callable<@Nullable JsonArray> callable) throws IllegalArgumentException {
return new SimpleMetric.Json<>(id, callable);
}

/**
* Create a JsonPromitive metric.
*
* @param id the source id
* @param callable the metric data callable
* @return the JsonPrimitive metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #getData()
* @since 0.28.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<JsonPrimitive> primitive(@SourceId final String id, final Callable<@Nullable JsonPrimitive> callable) throws IllegalArgumentException {
return new SimpleMetric.Json<>(id, callable);
}

/**
* Create a string array metric.
*
Expand All @@ -57,12 +114,12 @@ public interface Metric<T> {
* @return the string array metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<String[]> stringArray(@SourceId final String id, final Callable<String @Nullable []> callable) throws IllegalArgumentException {
return new ArrayMetric<>(id, callable);
return new SimpleMetric.Array<>(id, callable);
}

/**
Expand All @@ -73,12 +130,12 @@ static Metric<String[]> stringArray(@SourceId final String id, final Callable<St
* @return the boolean array metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Boolean[]> booleanArray(@SourceId final String id, final Callable<Boolean @Nullable []> callable) throws IllegalArgumentException {
return new ArrayMetric<>(id, callable);
return new SimpleMetric.Array<>(id, callable);
}

/**
Expand All @@ -89,12 +146,12 @@ static Metric<Boolean[]> booleanArray(@SourceId final String id, final Callable<
* @return the number array metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Number[]> numberArray(@SourceId final String id, final Callable<Number @Nullable []> callable) throws IllegalArgumentException {
return new ArrayMetric<>(id, callable);
return new SimpleMetric.Array<>(id, callable);
}

/**
Expand All @@ -105,12 +162,12 @@ static Metric<Number[]> numberArray(@SourceId final String id, final Callable<Nu
* @return the string map metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Map<String, ? extends String>> stringMap(@SourceId final String id, final Callable<? extends @Nullable Map<String, String>> callable) throws IllegalArgumentException {
return new MapMetric<>(id, callable);
return new SimpleMetric.Map<>(id, callable);
}

/**
Expand All @@ -121,12 +178,12 @@ static Metric<Number[]> numberArray(@SourceId final String id, final Callable<Nu
* @return the boolean map metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Map<String, ? extends Boolean>> booleanMap(@SourceId final String id, final Callable<? extends @Nullable Map<String, Boolean>> callable) throws IllegalArgumentException {
return new MapMetric<>(id, callable);
return new SimpleMetric.Map<>(id, callable);
}

/**
Expand All @@ -137,12 +194,12 @@ static Metric<Number[]> numberArray(@SourceId final String id, final Callable<Nu
* @return the number map metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Map<String, ? extends Number>> numberMap(@SourceId final String id, final Callable<? extends @Nullable Map<String, ? extends Number>> callable) throws IllegalArgumentException {
return new MapMetric<>(id, callable);
return new SimpleMetric.Map<>(id, callable);
}

/**
Expand All @@ -153,12 +210,12 @@ static Metric<Number[]> numberArray(@SourceId final String id, final Callable<Nu
* @return the boolean metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Boolean> bool(@SourceId final String id, final Callable<@Nullable Boolean> callable) throws IllegalArgumentException {
return new SingleValueMetric<>(id, callable);
return new SimpleMetric.Primitive<>(id, callable);
}

/**
Expand All @@ -169,12 +226,12 @@ static Metric<Boolean> bool(@SourceId final String id, final Callable<@Nullable
* @return the string metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<String> string(@SourceId final String id, final Callable<@Nullable String> callable) throws IllegalArgumentException {
return new SingleValueMetric<>(id, callable);
return new SimpleMetric.Primitive<>(id, callable);
}

/**
Expand All @@ -185,11 +242,11 @@ static Metric<String> string(@SourceId final String id, final Callable<@Nullable
* @return the number metric
* @throws IllegalArgumentException if the source id is invalid
* @apiNote The callable must be thread-safe and pure (i.e. not modify any shared state).
* @see #compute()
* @see #getData()
* @since 0.24.0
*/
@Contract(value = "_, _ -> new", pure = true)
static Metric<Number> number(@SourceId final String id, final Callable<@Nullable Number> callable) throws IllegalArgumentException {
return new SingleValueMetric<>(id, callable);
return new SimpleMetric.Primitive<>(id, callable);
}
}
Loading
Loading