a mini social media app for small communities
1module entity
2
3import db.pg
4import time
5import util
6
7pub struct User {
8pub mut:
9 id int @[primary; sql: serial]
10 username string @[unique]
11 nickname ?string
12
13 password string
14 password_salt string
15
16 muted bool
17 admin bool
18 automated bool
19
20 theme string
21 css string
22
23 bio string
24 pronouns string
25
26 created_at time.Time = time.now()
27}
28
29// get_name returns the user's nickname if it is not none, if so then their
30// username is returned.
31@[inline]
32pub fn (user User) get_name() string {
33 return user.nickname or { user.username }
34}
35
36// to_str_without_sensitive_data returns the stringified data for the user with
37// their password and salt censored.
38@[inline]
39pub fn (user User) to_str_without_sensitive_data() string {
40 return user.str()
41 .replace(user.password, '*'.repeat(16))
42 .replace(user.password_salt, '*'.repeat(16))
43}
44
45// User.from_row creates a user object from the given database row.
46// see src/database/user.v#search_for_users for usage.
47@[inline]
48pub fn User.from_row(res pg.Result, row pg.Row) User {
49 // curry some arguments for cleanliness
50 c := fn [res, row] (key string) ?string {
51 return util.get_row_col(res, row, key)
52 }
53 ct := fn [res, row] (key string) string {
54 return util.get_row_col_or_throw(res, row, key)
55 }
56
57 // this throws a cgen error when put in User{}
58 //todo: report this
59 created_at := time.parse(ct('created_at')) or { panic(err) }
60
61 return User{
62 id: ct('id').int()
63 username: ct('username')
64 nickname: if c('nickname') == none { none } else {
65 ct('nickname')
66 }
67 password: 'haha lol, nope'
68 password_salt: 'haha lol, nope'
69 muted: util.map_or_throw[string, bool](util.get_row_col(res, row, 'muted'), |it| it.bool())
70 admin: util.map_or_throw[string, bool](util.get_row_col(res, row, 'admin'), |it| it.bool())
71 theme: ct('theme')
72 bio: ct('bio')
73 pronouns: ct('pronouns')
74 created_at: created_at
75 }
76}