Pass proto in constructor

Makes the relation between the protobuf class and the wrapper more
direct. Conversion only happens at creates or on getters.
This commit is contained in:
Franck Royer 2021-05-10 16:07:43 +10:00
parent 3b7fc44419
commit e91f7933c9
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
4 changed files with 49 additions and 26 deletions

View File

@ -6,7 +6,11 @@ import { formatMessage } from './chat';
describe('CLI Chat app', () => { describe('CLI Chat app', () => {
it('Format message', () => { it('Format message', () => {
const date = new Date(234325324); const date = new Date(234325324);
const chatMessage = new ChatMessage(date, 'alice', 'Hello world!'); const chatMessage = ChatMessage.fromUtf8String(
date,
'alice',
'Hello world!'
);
expect(formatMessage(chatMessage)).to.match(/^<.*> alice: Hello world!$/); expect(formatMessage(chatMessage)).to.match(/^<.*> alice: Hello world!$/);
}); });

View File

@ -84,7 +84,7 @@ export default async function startChat(): Promise<void> {
rl.prompt(); rl.prompt();
for await (const line of rl) { for await (const line of rl) {
rl.prompt(); rl.prompt();
const chatMessage = new ChatMessage(new Date(), nick, line); const chatMessage = ChatMessage.fromUtf8String(new Date(), nick, line);
const msg = WakuMessage.fromBytes(chatMessage.encode(), ChatContentTopic); const msg = WakuMessage.fromBytes(chatMessage.encode(), ChatContentTopic);
await waku.relay.send(msg); await waku.relay.send(msg);
@ -129,5 +129,5 @@ export function formatMessage(chatMsg: ChatMessage): string {
minute: '2-digit', minute: '2-digit',
hour12: false, hour12: false,
}); });
return `<${timestamp}> ${chatMsg.nick}: ${chatMsg.message}`; return `<${timestamp}> ${chatMsg.nick}: ${chatMsg.payloadAsUtf8}`;
} }

View File

@ -11,14 +11,14 @@ describe('Chat Message', function () {
fc.string(), fc.string(),
fc.string(), fc.string(),
(timestamp, nick, message) => { (timestamp, nick, message) => {
const msg = new ChatMessage(timestamp, nick, message); const msg = ChatMessage.fromUtf8String(timestamp, nick, message);
const buf = msg.encode(); const buf = msg.encode();
const actual = ChatMessage.decode(buf); const actual = ChatMessage.decode(buf);
// Date.toString does not include ms, as we loose this precision by design // Date.toString does not include ms, as we loose this precision by design
expect(actual.timestamp.toString()).to.eq(timestamp.toString()); expect(actual.timestamp.toString()).to.eq(timestamp.toString());
expect(actual.nick).to.eq(nick); expect(actual.nick).to.eq(nick);
expect(actual.message).to.eq(message); expect(actual.payloadAsUtf8).to.eq(message);
} }
) )
); );

View File

@ -4,33 +4,52 @@ import * as proto from '../../proto/chat/v2/chat_message';
// TODO: Move to waku library? // TODO: Move to waku library?
export class ChatMessage { export class ChatMessage {
public constructor( public constructor(public proto: proto.ChatMessage) {}
public timestamp: Date,
public nick: string, /**
public message: string * Create Chat Message with a utf-8 string as payload.
) {} */
static fromUtf8String(
timestamp: Date,
nick: string,
text: string
): ChatMessage {
const timestampNumber = Math.floor(timestamp.valueOf() / 1000);
const payload = Buffer.from(text, 'utf-8');
return new ChatMessage({
timestamp: timestampNumber,
nick,
payload,
});
}
static decode(bytes: Uint8Array): ChatMessage { static decode(bytes: Uint8Array): ChatMessage {
const protoMsg = proto.ChatMessage.decode(Reader.create(bytes)); const protoMsg = proto.ChatMessage.decode(Reader.create(bytes));
const timestamp = new Date(protoMsg.timestamp * 1000); return new ChatMessage(protoMsg);
const message = protoMsg.payload
? Array.from(protoMsg.payload)
.map((char) => {
return String.fromCharCode(char);
})
.join('')
: '';
return new ChatMessage(timestamp, protoMsg.nick, message);
} }
encode(): Uint8Array { encode(): Uint8Array {
const timestamp = Math.floor(this.timestamp.valueOf() / 1000); return proto.ChatMessage.encode(this.proto).finish();
const payload = Buffer.from(this.message, 'utf-8'); }
return proto.ChatMessage.encode({ get timestamp(): Date {
timestamp, return new Date(this.proto.timestamp * 1000);
nick: this.nick, }
payload,
}).finish(); get nick(): string {
return this.proto.nick;
}
get payloadAsUtf8(): string {
if (!this.proto.payload) {
return '';
}
return Array.from(this.proto.payload)
.map((char) => {
return String.fromCharCode(char);
})
.join('');
} }
} }