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', () => {
it('Format message', () => {
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!$/);
});

View File

@ -84,7 +84,7 @@ export default async function startChat(): Promise<void> {
rl.prompt();
for await (const line of rl) {
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);
await waku.relay.send(msg);
@ -129,5 +129,5 @@ export function formatMessage(chatMsg: ChatMessage): string {
minute: '2-digit',
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(),
(timestamp, nick, message) => {
const msg = new ChatMessage(timestamp, nick, message);
const msg = ChatMessage.fromUtf8String(timestamp, nick, message);
const buf = msg.encode();
const actual = ChatMessage.decode(buf);
// Date.toString does not include ms, as we loose this precision by design
expect(actual.timestamp.toString()).to.eq(timestamp.toString());
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?
export class ChatMessage {
public constructor(
public timestamp: Date,
public nick: string,
public message: string
) {}
public constructor(public proto: proto.ChatMessage) {}
/**
* 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 {
const protoMsg = proto.ChatMessage.decode(Reader.create(bytes));
const timestamp = new Date(protoMsg.timestamp * 1000);
const message = protoMsg.payload
? Array.from(protoMsg.payload)
.map((char) => {
return String.fromCharCode(char);
})
.join('')
: '';
return new ChatMessage(timestamp, protoMsg.nick, message);
return new ChatMessage(protoMsg);
}
encode(): Uint8Array {
const timestamp = Math.floor(this.timestamp.valueOf() / 1000);
const payload = Buffer.from(this.message, 'utf-8');
return proto.ChatMessage.encode(this.proto).finish();
}
return proto.ChatMessage.encode({
timestamp,
nick: this.nick,
payload,
}).finish();
get timestamp(): Date {
return new Date(this.proto.timestamp * 1000);
}
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('');
}
}