-- vim: ft=terra
local m = {
timepoint = uint64;
scope = lib.enum {
'public', 'private', 'local';
'personal', 'direct', 'circle';
};
notiftype = lib.enum {
'mention', 'like', 'rt', 'react'
};
relation = lib.enum {
'follow', 'mute', 'block'
};
credset = lib.set {
'pw', 'otp', 'challenge', 'trust'
};
}
local str = rawstring --lib.mem.ptr(int8)
struct m.source
struct m.rights {
rank: uint16 -- lower = more powerful except 0 = regular user
-- creating staff automatically assigns rank immediately below you
quota: uint32 -- # of allowed tweets per day; 0 = no limit
-- user powers -- default on
login: bool
visible: bool
post: bool
shout: bool
propagate: bool
upload: bool
-- admin powers -- default off
ban: bool
config: bool
censor: bool
suspend: bool
rebrand: bool -- modify site's brand identity
}
terra m.rights_default()
return m.rights {
rank = 0, quota = 1000;
login = true, visible = true, post = true;
shout = true, propagate = true, upload = true;
ban = false, config = false, censor = false;
suspend = false, rebrand = false;
}
end
struct m.actor {
id: uint64
nym: str
handle: str
origin: uint64
bio: str
rights: m.rights
key: lib.mem.ptr(uint8)
xid: str
source: &m.source
}
struct m.range {
time: bool
union {
from_time: m.timepoint
from_idx: uint64
}
union {
to_time: m.timepoint
to_idx: uint64
}
}
struct m.post {
id: uint64
author: uint64
subject: str
body: str
posted: m.timepoint
discovered: m.timepoint
scope: m.scope.t
mentions: lib.mem.ptr(uint64)
circles: lib.mem.ptr(uint64) --only meaningful if scope is set to circle
convo: uint64
parent: uint64
source: &m.source
}
local cnf = terralib.memoize(function(ty,rty)
rty = rty or ty
return struct {
enum: {&opaque, uint64, rawstring} -> intptr
get: {&opaque, uint64, rawstring} -> rty
set: {&opaque, uint64, rawstring, ty} -> {}
reset: {&opaque, uint64, rawstring} -> {}
}
end)
struct m.notif {
kind: m.notiftype.t
when: uint64
union {
post: uint64
reaction: int8[8]
}
}
struct m.inet {
pv: uint8 -- 0 = null, 4 = ipv4, 6 = ipv6
union {
v4: uint8[4]
v6: uint8[16]
}
union {
fixbits: uint8 -- for cidr
port: uint16 -- for origin
}
}
terra m.inet:cidr_str()
if self.pv == 4 then
var maxsz = 3*4 + 3 + 1
elseif self.pv == 6 then
var bits = 128
var bytes = bits / 8
var hexchs = bytes * 2
var segs = hexchs / 4
var seps = segs - 1
var maxsz = hexchs + seps + 1
else return nil end
end
struct m.auth {
aid: uint64
uid: uint64
aname: str
netmask: m.inet
restrict: lib.mem.ptr(rawstring)
blacklist: bool
}
-- backends only handle content on the local server
struct m.backend { id: rawstring
open: &m.source -> &opaque
close: &m.source -> {}
conf_get: {&m.source, rawstring} -> lib.mem.ptr(int8)
conf_set: {&m.source, rawstring, rawstring} -> {}
conf_reset: {&m.source, rawstring} -> {}
actor_save: {&m.source, m.actor} -> bool
actor_create: {&m.source, m.actor} -> bool
actor_fetch_xid: {&m.source, rawstring} -> lib.mem.ptr(m.actor)
actor_fetch_uid: {&m.source, uint64} -> lib.mem.ptr(m.actor)
actor_notif_fetch_uid: {&m.source, uint64} -> lib.mem.ptr(m.notif)
actor_enum: {&m.source} -> lib.mem.ptr(&m.actor)
actor_enum_local: {&m.source} -> lib.mem.ptr(&m.actor)
actor_auth_how: {&m.source, m.inet, rawstring} -> m.credset
-- returns a set of auth method categories that are available for a
-- given user from a certain origin
-- origin: inet
-- handle: rawstring
actor_auth_otp: {&m.source, m.inet, rawstring, rawstring} -> uint64
actor_auth_pw: {&m.source, m.inet, rawstring, rawstring} -> uint64
-- handles password-based logins against hashed passwords
-- origin: inet
-- handle: rawstring
-- token: rawstring
actor_auth_tls: {&m.source, m.inet, rawstring} -> uint64
-- handles implicit authentication performed as part of an TLS connection
-- origin: inet
-- fingerprint: rawstring
actor_auth_api: {&m.source, m.inet, rawstring, rawstring} -> uint64
-- handles API authentication
-- origin: inet
-- handle: rawstring
-- key: rawstring (X-API-Key)
actor_auth_record_fetch: {&m.source, uint64} -> lib.mem.ptr(m.auth)
actor_conf_str: cnf(rawstring, lib.mem.ptr(int8))
actor_conf_int: cnf(intptr, lib.stat(intptr))
post_save: {&m.source, &m.post} -> bool
post_create: {&m.source, &m.post} -> bool
actor_post_fetch_uid: {&m.source, uint64, m.range} -> lib.mem.ptr(m.post)
convo_fetch_xid: {&m.source,rawstring} -> lib.mem.ptr(m.post)
convo_fetch_uid: {&m.source,uint64} -> lib.mem.ptr(m.post)
actor_timeline_fetch_uid: {&m.source, uint64, m.range} -> lib.mem.ptr(m.post)
instance_timeline_fetch: {&m.source, m.range} -> lib.mem.ptr(m.post)
}
struct m.source {
backend: &m.backend
id: lib.mem.ptr(int8)
handle: &opaque
string: lib.mem.ptr(int8)
}
terra m.source:free()
self.id:free()
self.string:free()
end
m.source.metamethods.__methodmissing = macro(function(meth, obj, ...)
local q = {...}
-- syntax sugar to forward unrecognized calls onto the backend
return `obj.backend.[meth](&obj, [q])
end)
return m