volvox/service-chats/src/main/java/io/volvox/chats/ChatId.java

117 lines
4.1 KiB
Java

package io.volvox.chats;
public record ChatId(Type type, long subId) {
public static final int SUB_ID_MASK_BYTES = 52;
public static final int TYPE_MASK_BYTES = 2;
public static final long SUB_ID_MASK = 0b001111111111111111111111111111111111111111111111111111L;
public static final long TYPE_MASK = 0b11L << SUB_ID_MASK_BYTES;
public static final long MASK = SUB_ID_MASK | TYPE_MASK;
public static final int TYPE_PRIVATE_INT = 0b00;
public static final int TYPE_BASIC_INT = 0b01;
public static final int TYPE_SUPER_INT = 0b10;
public static final int TYPE_SECRET_INT = 0b11;
public static final long TYPE_PRIVATE_LONG = 0;
public static final long TYPE_BASIC_LONG = 0b01L << SUB_ID_MASK_BYTES & TYPE_MASK;
public static final long TYPE_SUPER_LONG = 0b10L << SUB_ID_MASK_BYTES & TYPE_MASK;
public static final long TYPE_SECRET_LONG = 0b11L << SUB_ID_MASK_BYTES & TYPE_MASK;
public ChatId {
if ((subId & SUB_ID_MASK) != subId) {
throw new IllegalArgumentException("subId is too big");
}
}
public static ChatId fromLong(long id) {
return new ChatId(getType(id), getIdLong(id));
}
private static Type getType(long id) {
return switch ((int) ((id & TYPE_MASK) >> SUB_ID_MASK_BYTES)) {
case TYPE_SUPER_INT -> Type.SUPER;
case TYPE_BASIC_INT -> Type.BASIC;
case TYPE_PRIVATE_INT -> Type.PRIVATE;
case TYPE_SECRET_INT -> Type.SECRET;
default -> throw new IllegalArgumentException("Invalid id type: " + id);
};
}
private static long getIdLong(long id) {
return id & SUB_ID_MASK;
}
public long toLong() {
return switch (type) {
case SUPER -> TYPE_SUPER_LONG;
case BASIC -> TYPE_BASIC_LONG;
case PRIVATE -> TYPE_PRIVATE_LONG;
case SECRET -> TYPE_SECRET_LONG;
} | (subId & SUB_ID_MASK);
}
public enum Type {
PRIVATE,
BASIC,
SUPER,
SECRET
}
@Override
public String toString() {
return toString(this);
}
public static String toString(ChatId chatId) {
return Long.toUnsignedString(chatId.subId) + "-" + switch (chatId.type) {
case SUPER -> 's';
case BASIC -> 'b';
case PRIVATE -> 'u';
case SECRET -> 'd';
};
}
public static String toString(long chatId) {
return Long.toUnsignedString(getIdLong(chatId)) + "-" + switch (getType(chatId)) {
case SUPER -> 's';
case BASIC -> 'b';
case PRIVATE -> 'u';
case SECRET -> 'd';
};
}
public static ChatId fromString(String chatId) {
var parts = chatId.split("-", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Malformed chat id");
}
if (parts[1].length() != 1) {
throw new IllegalArgumentException("Chat type is too long");
}
return new ChatId(switch(parts[1].charAt(0)) {
case 's' -> Type.SUPER;
case 'b' -> Type.BASIC;
case 'u' -> Type.PRIVATE;
case 'd' -> Type.SECRET;
default -> throw new IllegalStateException("Unexpected value: " + parts[1].charAt(0));
}, Long.parseUnsignedLong(parts[0]) & SUB_ID_MASK);
}
public static Long stringToLong(String chatId) {
var parts = chatId.split("-", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Malformed chat id");
}
if (parts[1].length() != 1) {
throw new IllegalArgumentException("Chat type is too long");
}
return switch(parts[1].charAt(0)) {
case 's' -> TYPE_SUPER_LONG;
case 'b' -> TYPE_BASIC_LONG;
case 'u' -> TYPE_PRIVATE_LONG;
case 'd' -> TYPE_SECRET_LONG;
default -> throw new IllegalStateException("Unexpected value: " + parts[1].charAt(0));
} | (Long.parseUnsignedLong(parts[0]) & SUB_ID_MASK);
}
}