Seeking a more elegant way to model a User object
I've been using Effect for a bit, and the following code works, but I'm unsure if there's a better more elegant way to do it.
Not looking for solutions, just ideas. Is there a better way to model my User object (class?) and avoid the separate functions perhaps?
Not looking for solutions, just ideas. Is there a better way to model my User object (class?) and avoid the separate functions perhaps?
import * as Schema from '@effect/schema/Schema';
import * as Effect from 'effect/Effect';
import {DbRecordParseError} from '../lib/errors.server.ts';
import * as DateString from './date.server.ts';
import * as Email from './email.server.ts';
import * as Uuid from './uuid.server.ts';
const UserBrand = Symbol.for('UserBrand');
const UserIdBrand = Symbol.for('UserIdBrand');
class ParseUserIdError {
readonly _tag = 'ParseUserIdError';
}
class ParseUserError {
readonly _tag = 'ParseUserError';
}
export const userNameSchema = Schema.Trim.pipe(
Schema.minLength(2, {
message: () => 'Name must be at least 2 characters',
}),
Schema.maxLength(100, {
message: () => 'Name cannot be more than 100 characters',
})
);
export const userIdSchema = Uuid.uuidSchema.pipe(Schema.brand(UserIdBrand));
export const userSchema = Schema.struct({
id: userIdSchema,
name: userNameSchema,
email: Email.emailSchema,
emailVerified: Schema.boolean,
createdAt: DateString.dateSchema,
updatedAt: DateString.dateSchema,
}).pipe(Schema.brand(UserBrand));
export type User = Schema.Schema.To<typeof userSchema>;
export function parse(value: unknown) {
return Effect.try({
try: () => Schema.parseSync(userSchema)(value),
catch: () => new ParseUserError(),
});
}
export function parseId(value: unknown) {
return Effect.try({
try: () => Schema.parseSync(userIdSchema)(value),
catch: () => new ParseUserIdError(),
});
}import * as Schema from '@effect/schema/Schema';
import * as Effect from 'effect/Effect';
import {DbRecordParseError} from '../lib/errors.server.ts';
import * as DateString from './date.server.ts';
import * as Email from './email.server.ts';
import * as Uuid from './uuid.server.ts';
const UserBrand = Symbol.for('UserBrand');
const UserIdBrand = Symbol.for('UserIdBrand');
class ParseUserIdError {
readonly _tag = 'ParseUserIdError';
}
class ParseUserError {
readonly _tag = 'ParseUserError';
}
export const userNameSchema = Schema.Trim.pipe(
Schema.minLength(2, {
message: () => 'Name must be at least 2 characters',
}),
Schema.maxLength(100, {
message: () => 'Name cannot be more than 100 characters',
})
);
export const userIdSchema = Uuid.uuidSchema.pipe(Schema.brand(UserIdBrand));
export const userSchema = Schema.struct({
id: userIdSchema,
name: userNameSchema,
email: Email.emailSchema,
emailVerified: Schema.boolean,
createdAt: DateString.dateSchema,
updatedAt: DateString.dateSchema,
}).pipe(Schema.brand(UserBrand));
export type User = Schema.Schema.To<typeof userSchema>;
export function parse(value: unknown) {
return Effect.try({
try: () => Schema.parseSync(userSchema)(value),
catch: () => new ParseUserError(),
});
}
export function parseId(value: unknown) {
return Effect.try({
try: () => Schema.parseSync(userIdSchema)(value),
catch: () => new ParseUserIdError(),
});
}