Skip to content

Instantly share code, notes, and snippets.

@ochafik

ochafik/tspb.ts Secret

Last active October 5, 2016 18:49
Show Gist options
  • Select an option

  • Save ochafik/3066d87f25b4e48f7301e5b477778a74 to your computer and use it in GitHub Desktop.

Select an option

Save ochafik/3066d87f25b4e48f7301e5b477778a74 to your computer and use it in GitHub Desktop.
TypeScript protobufs
export type FieldDesc<T, F> = {
id: number,
getter: (instance: T) => F,
setter: (instance: T, value: F) => void,
desc?: MessageDesc<F>
}
export class MessageDesc<T> {
constructor(private fields: FieldDesc<T, any>[]) {}
toJson(instance: T): any {
const result = Object.create(null);
for (const field of this.fields) {
const value = field.getter(instance);
if (value != null) {
result[field.id] = value;
}
}
return result;
}
fromJson(json: any): T {
const result: T = Object.create(null);
for (const field of this.fields) {
const value = json[field.id];
if (value != null) {
field.setter(result, value);
}
}
return result;
}
toJspb(instance: T): any { throw 'TODO'; }
fromJspb(instance: any): T { throw 'TODO'; }
}
import SearchResult from 'goog:proto.javascript.angular2.codelab.protos.SearchResult';
import {MessageDesc} from './tspb';
export type TsPbSearchResult = {
etag?: string, // 201
id?: TsPbResourceId, // 1
kind?: string, // 200
snippet?: TsPbSearchResultSnippet, // 2
statistics?: TsPbVideoStatistics, // 202
};
export type TsPbResourceId = {};
export type TsPbSearchResultSnippet = {};
export type uint64 = number;
export type TsPbVideoStatistics = {
commentCount?: uint64, // 5
dislikeCount?: uint64, // 3
favoriteCount?: uint64, // 4
likeCount?: uint64, // 2
viewCount?: uint64, // 1
};
export const TsPbVideoStatistics = new MessageDesc<TsPbVideoStatistics>([
{id: 1, getter: i => i.viewCount, setter: (i, v) => i.viewCount = v},
{id: 2, getter: i => i.likeCount, setter: (i, v) => i.likeCount = v},
{id: 3, getter: i => i.dislikeCount, setter: (i, v) => i.dislikeCount = v},
{id: 4, getter: i => i.favoriteCount, setter: (i, v) => i.favoriteCount = v},
{id: 5, getter: i => i.commentCount, setter: (i, v) => i.commentCount = v},
]);
export const TsPbResourceId = new MessageDesc<TsPbResourceId>([]);
export const TsPbSearchResultSnippet = new MessageDesc<TsPbSearchResultSnippet>([]);
export const TsPbSearchResult = new MessageDesc<TsPbSearchResult>([
{id: 201, getter: i => i.etag, setter: (i, v) => i.etag = v},
{id: 1, getter: i => i.id, setter: (i, v) => i.id = v, desc: TsPbResourceId},
{id: 200, getter: i => i.kind, setter: (i, v) => i.kind = v},
{id: 2, getter: i => i.snippet, setter: (i, v) => i.snippet = v, desc: TsPbSearchResultSnippet},
{id: 202, getter: i => i.statistics, setter: (i, v) => i.statistics = v, desc: TsPbVideoStatistics},
]);
var res: TsPbSearchResultSnippet = {
}
//new MessageDesc<
// export const TsPbSearchResult = new MessageDesc<TsPbSearchResult>([], SearchResult.deserialize);
/*
message Foo {
optional string bar = 1;
repeated string bars = 2;
}
*/
type Sub = {
s?: string
};
const Sub = new MessageDesc<Sub>([
{id: 0, getter: (i: Sub) => i.s, setter: (i: Sub, v: string) => i.s = v},
]);
type Foo = {
bar?: string,
bars?: string[],
sub?: Sub,
};
const Foo = new MessageDesc<Foo>([
{
id: 0, getter: i => i.bar, setter: (i, v) => i.bar = v
},
{
id: 1, getter: i => i.bars, setter: (i, v) => i.bars = v
},
{
id: 2, getter: i => i.sub, setter: (i, v) => i.sub = v, desc: Sub
},
]);
var f: Foo = {bar: "a", bars: []};
expect(Foo.toJson(f)).toBe({1:"a", 2:["a", "b"]});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment