-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathIdentifier.java
More file actions
134 lines (112 loc) · 4.4 KB
/
Identifier.java
File metadata and controls
134 lines (112 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package net.modificationstation.stationapi.api.util;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import static net.modificationstation.stationapi.api.util.Namespace.MINECRAFT;
public final class Identifier implements Comparable<@NotNull Identifier> {
@NotNull
public static final Codec<@NotNull Identifier> CODEC = Codec.STRING.comapFlatMap(s -> {
try {
return DataResult.success(of(s));
} catch (final IllegalArgumentException var2) {
return DataResult.error(() -> "Not a valid identifier: " + s + " " + var2.getMessage());
}
}, Identifier::toString).stable();
public static final char NAMESPACE_SEPARATOR = ':';
private record IdentifierCacheKey(@NotNull Namespace namespace, @NotNull String id) {}
@NotNull
private static final Cache<@NotNull IdentifierCacheKey, @NotNull Identifier> CACHE = CacheBuilder.newBuilder().softValues().build();
@NotNull
private static final Function<@NotNull IdentifierCacheKey, @NotNull Identifier> IDENTIFIER_FACTORY = Identifier::new;
public static @NotNull Identifier of(@NotNull final String identifier) {
final int i = identifier.indexOf(NAMESPACE_SEPARATOR);
final String namespace;
final String path;
if (i < 0) {
namespace = MINECRAFT.toString();
path = identifier;
} else {
namespace = identifier.substring(0, i);
path = identifier.substring(i + 1);
}
return of(Namespace.of(namespace), path);
}
public static @NotNull Identifier of(@NotNull final Namespace namespace, @NotNull final String id) {
final var key = new IdentifierCacheKey(namespace, id);
try {
return CACHE.get(key, () -> IDENTIFIER_FACTORY.apply(key));
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
public static @Nullable Identifier tryParse(@NotNull final String string) {
try {
return of(string);
} catch (@NotNull final IllegalArgumentException e) {
return null;
}
}
public static @NotNull DataResult<@NotNull Identifier> validate(@NotNull final String id) {
try {
return DataResult.success(of(id));
} catch (@NotNull final IllegalArgumentException e) {
return DataResult.error(() -> "Not a valid identifier: " + id + " " + e.getMessage());
}
}
@NotNull
@Getter
public final Namespace namespace;
@NotNull
@Getter
public final String path;
@NotNull
private final String toString;
private final int hashCode;
private Identifier(@NotNull final IdentifierCacheKey key) {
namespace = key.namespace;
path = key.id;
toString = namespace + String.valueOf(NAMESPACE_SEPARATOR) + path;
hashCode = toString.hashCode();
}
public @NotNull Identifier withPath(@NotNull final String path) {
return of(namespace, path);
}
public @NotNull Identifier withPath(@NotNull final UnaryOperator<String> pathFunction) {
return withPath(pathFunction.apply(path));
}
public @NotNull Identifier withPrefixedPath(@NotNull final String prefix) {
return withPath(prefix + path);
}
public @NotNull Identifier withSuffixedPath(@NotNull final String suffix) {
return withPath(path + suffix);
}
@Override
public int compareTo(@NotNull final Identifier o) {
return toString.compareTo(o.toString);
}
@Override
public @NotNull String toString() {
return toString;
}
@Override
public boolean equals(@NotNull final Object other) {
if (this == other) return true;
if (other instanceof @NotNull final Identifier otherId) {
if (toString.equals(otherId.toString))
throw new IllegalStateException(String.format("Encountered a duplicate instance of Identifier %s!", toString));
return false;
}
return toString.equals(other);
}
@Override
public int hashCode() {
return hashCode;
}
}