Types are now bidirectional

It is still possible to define types as functions (Buffer => string for 
state topics, string => Buffer for command topics). Otherwise types have 
from and to properties.
(Fixes #101)
This commit is contained in:
uwap 2020-10-19 05:45:09 +02:00
parent 2997ff8862
commit ccd9bcd3b5
7 changed files with 64 additions and 38 deletions

View file

@ -1,16 +1,22 @@
// @flow
import type { Icon } from "config/icon";
export type TopicType = (msg: Buffer) => string;
export type TopicType = {
from: (msg: Buffer) => string,
to: (newstate: string) => Buffer
};
export type StateCommand = {
export type StateTopicType = TopicType | ((msg: Buffer) => string);
export type CommandTopicType = TopicType | ((newstate: string) => Buffer);
export type StateCommand<T> = {
name: string,
type: TopicType
type: T
}
export type Topic = {
state?: StateCommand,
command?: StateCommand,
state?: StateCommand<StateTopicType>,
command?: StateCommand<CommandTopicType>,
defaultValue: string
};
export type Topics = Map<string, Topic>;
@ -114,6 +120,17 @@ export type Space = {
mqtt: string
};
export type Layer = {
image: string,
name: string,
baseLayer?: boolean,
defaultVisibility: "visible" | "hidden",
opacity?: number,
bounds: {
topLeft: Point,
bottomRight: Point
}
};
export type Config = {
space: Space,
topics: Topics | Array<Topics>,

View file

@ -1,13 +1,22 @@
// @flow
import type { TopicType } from "config/flowtypes";
import at from "lodash/at";
import set from "lodash/set";
export const string: TopicType = (msg: Buffer) => msg.toString();
export const string: TopicType = {
from: (msg: Buffer) => msg.toString(),
to: (msg: string) => Buffer.from(msg)
};
export const json = (path: string, innerType?: TopicType): TopicType => {
const parseAgain = innerType == null ? (x) => x.toString() : innerType;
return (msg) => parseAgain(Buffer.from(
at(JSON.parse(msg.toString()), path)[0].toString()));
const parseAgain = innerType?.from ?? ((x) => x.toString());
const parseFirst = innerType?.to ?? ((x) => Buffer.from(x));
return {
from: (msg) => parseAgain(Buffer.from(
at(JSON.parse(msg.toString()), path)[0].toString())),
to: (msg) => Buffer.from(
JSON.serialize(set({}, path, parseFirst(msg).toString())))
};
};
export type TypeOptionParam = { otherwise?: string, [string]: string };
@ -16,13 +25,17 @@ export const option = (values: TypeOptionParam): TopicType => {
if (values.otherwise != null) {
return values.otherwise;
} else {
throw new Error(
`Value ${x.toString()} cannot be mapped by the option parameters given`
);
return x;
}
};
const mapVal = (x) => (values[x] != null ? values[x] : defaultValue(x));
return (x) => mapVal(x.toString());
return {
from: (x) => mapVal(x.toString()),
to: (x) => Buffer.from(mapVal(x))
};
};
export const jsonArray = (msg: Buffer) => JSON.parse(msg.toString()).join(", ");
export const jsonArray = {
from: (msg: Buffer) => JSON.parse(msg.toString()).join(", "),
to: (msg: string) => Buffer.from(`[${msg}]`)
};