mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-25 03:49:11 +00:00
chore: document protoReflection.ts
This commit is contained in:
parent
04c8e6619d
commit
eb5355f881
1 changed files with 17 additions and 0 deletions
|
@ -1,26 +1,43 @@
|
||||||
import * as pbjs from 'google-protobuf';
|
import * as pbjs from 'google-protobuf';
|
||||||
|
|
||||||
|
// Protobuf Message itself
|
||||||
type GenericObject<T extends pbjs.Message> = T;
|
type GenericObject<T extends pbjs.Message> = T;
|
||||||
|
|
||||||
|
// Message's "setter" call
|
||||||
type ProtoFunction<T extends pbjs.Message, U extends ReturnType<T['toObject']>> = (
|
type ProtoFunction<T extends pbjs.Message, U extends ReturnType<T['toObject']>> = (
|
||||||
value: U[keyof U]
|
value: U[keyof U]
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AsObjectToProto does the opposite of ProtoMessage.toObject().
|
||||||
|
* This function turns regular JS objects back into their source protobuf message type,
|
||||||
|
* with the help us copious amounts of reflection.
|
||||||
|
* @param protoClass A protobuf message class
|
||||||
|
* @param input A JS object that corresponds to the protobuf message class.
|
||||||
|
*/
|
||||||
export const AsObjectToProto = <T extends pbjs.Message>(
|
export const AsObjectToProto = <T extends pbjs.Message>(
|
||||||
protoClass: { new (): T },
|
protoClass: { new (): T },
|
||||||
input: ReturnType<T['toObject']>
|
input: ReturnType<T['toObject']>
|
||||||
): GenericObject<T> => {
|
): GenericObject<T> => {
|
||||||
|
// First, we create the message itself
|
||||||
const proto = new protoClass();
|
const proto = new protoClass();
|
||||||
|
|
||||||
|
// We want the keys from the message, this will give us the setter names we need.
|
||||||
const protoKeys = Object.getOwnPropertyNames((proto as any).__proto__);
|
const protoKeys = Object.getOwnPropertyNames((proto as any).__proto__);
|
||||||
|
|
||||||
|
// Loop over the input data keys
|
||||||
for (let inputKey in input) {
|
for (let inputKey in input) {
|
||||||
|
// As we loop, find the setter function for the key
|
||||||
const setCallName = protoKeys.find(
|
const setCallName = protoKeys.find(
|
||||||
(key) => `set${inputKey.toLowerCase()}` === key.toLowerCase()
|
(key) => `set${inputKey.toLowerCase()}` === key.toLowerCase()
|
||||||
) as keyof typeof proto;
|
) as keyof typeof proto;
|
||||||
|
|
||||||
|
// If we encounter a key without a place to go, we silently ignore it.
|
||||||
if (!setCallName) {
|
if (!setCallName) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// But, if it all succeeds, we call the setter with the JS object's value.
|
||||||
((proto[setCallName] as unknown) as ProtoFunction<T, typeof input>)(
|
((proto[setCallName] as unknown) as ProtoFunction<T, typeof input>)(
|
||||||
input[inputKey]
|
input[inputKey]
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue