export const AddressTypeId: unique symbol = Symbol.for(
'@spiko/Address'
);
export type AddressTypeId = typeof AddressTypeId;
export interface Address {
readonly [AddressTypeId]: AddressTypeId;
}
export const isAddress = (a: unknown): a is Address =>
Predicate.hasProperty(a, AddressTypeId);
export class AddressFactory extends Context.Tag(
'@services/AddressFactory'
)<
AddressFactory,
{
readonly fromString: (
s: string
) => Effect.Effect<Address, ParseResult.ParseIssue>;
readonly toString: (
a: Address
) => Effect.Effect<string, ParseResult.ParseIssue>;
}
>() {}
const AddressSchemaFromSelf = Schema.declare((a) =>
isAddress(a)
);
export const Address: Schema.Schema<
Address,
string,
AddressFactory
> = Schema.String.pipe(
Schema.transformOrFail(AddressSchemaFromSelf, {
encode: (a) =>
AddressFactory.pipe(Effect.flatMap((f) => f.toString(a))),
decode: (s) =>
AddressFactory.pipe(Effect.flatMap((f) => f.fromString(s))),
})
);
export const AddressTypeId: unique symbol = Symbol.for(
'@spiko/Address'
);
export type AddressTypeId = typeof AddressTypeId;
export interface Address {
readonly [AddressTypeId]: AddressTypeId;
}
export const isAddress = (a: unknown): a is Address =>
Predicate.hasProperty(a, AddressTypeId);
export class AddressFactory extends Context.Tag(
'@services/AddressFactory'
)<
AddressFactory,
{
readonly fromString: (
s: string
) => Effect.Effect<Address, ParseResult.ParseIssue>;
readonly toString: (
a: Address
) => Effect.Effect<string, ParseResult.ParseIssue>;
}
>() {}
const AddressSchemaFromSelf = Schema.declare((a) =>
isAddress(a)
);
export const Address: Schema.Schema<
Address,
string,
AddressFactory
> = Schema.String.pipe(
Schema.transformOrFail(AddressSchemaFromSelf, {
encode: (a) =>
AddressFactory.pipe(Effect.flatMap((f) => f.toString(a))),
decode: (s) =>
AddressFactory.pipe(Effect.flatMap((f) => f.fromString(s))),
})
);