module entity import db.pg import time import util pub struct User { pub mut: id int @[primary; sql: serial] username string @[unique] nickname ?string password string password_salt string muted bool admin bool automated bool theme string css string bio string pronouns string created_at time.Time = time.now() } // get_name returns the user's nickname if it is not none, if so then their // username is returned. @[inline] pub fn (user User) get_name() string { return user.nickname or { user.username } } // to_str_without_sensitive_data returns the stringified data for the user with // their password and salt censored. @[inline] pub fn (user User) to_str_without_sensitive_data() string { return user.str() .replace(user.password, '*'.repeat(16)) .replace(user.password_salt, '*'.repeat(16)) } // User.from_row creates a user object from the given database row. // see src/database/user.v#search_for_users for usage. @[inline] pub fn User.from_row(res pg.Result, row pg.Row) User { // curry some arguments for cleanliness c := fn [res, row] (key string) ?string { return util.get_row_col(res, row, key) } ct := fn [res, row] (key string) string { return util.get_row_col_or_throw(res, row, key) } // this throws a cgen error when put in User{} //todo: report this created_at := time.parse(ct('created_at')) or { panic(err) } return User{ id: ct('id').int() username: ct('username') nickname: if c('nickname') == none { none } else { ct('nickname') } password: 'haha lol, nope' password_salt: 'haha lol, nope' muted: util.map_or_throw[string, bool](util.get_row_col(res, row, 'muted'), |it| it.bool()) admin: util.map_or_throw[string, bool](util.get_row_col(res, row, 'admin'), |it| it.bool()) theme: ct('theme') bio: ct('bio') pronouns: ct('pronouns') created_at: created_at } }