import {isFunction, isBlank} from './lang'; import { Converter, composeConverters, identityConverter, EncodingException } from './converter'; export {Converter, EncodingException}; export interface Codec { encode: Converter; decode: Converter; } export function isCodec(obj: any): boolean { return !isBlank(obj) && isFunction(obj.decode) && isFunction(obj.encode); } export function getEncoder(obj: Codec | Converter): Converter{ if (!isCodec(obj)) { if (isFunction(obj)) return obj as Converter; throw new TypeError(`object is not a codec or converter: ${obj}`); } return (obj as Codec).encode.bind(obj) as Converter; } export function getDecoder(obj: Codec | Converter): Converter { if (!isCodec(obj)) { if (isFunction(obj)) return obj as Converter; throw new TypeError(`object is not a codec: ${obj}`); } return (obj as Codec).decode.bind(obj); } export function composeCodecs(fst: Codec, snd: Codec): Codec { return { encode: composeConverters(fst.encode, snd.encode), decode: composeConverters(snd.decode, fst.decode) }; } export function chainCodecs(...codecs: Codec[]) { return codecs.reduce(composeCodecs, identity); } export const identity: Codec = { encode: identityConverter, decode: identityConverter };