anvilsign in

collin/anvil

1//! Core domain model, persistence, and on-disk repository storage for anvil.
2//!
3//! This crate is transport-agnostic: it knows about users, repositories, the
4//! SQLite database, and bare git repositories on disk, but nothing about HTTP,
5//! SSH, or the git wire protocol. Higher layers (`anvil-web`, `anvil-ssh`,
6//! `anvil-git`) build on top of it.
7
8pub mod access;
9pub mod config;
10pub mod db;
11pub mod error;
12pub mod models;
13pub mod repos;
14pub mod sessions;
15pub mod ssh_keys;
16pub mod storage;
17pub mod users;
18
19pub use config::Config;
20pub use error::{
21 Error,
22 Result,
23};
24pub use models::{
25 Repository,
26 Session,
27 SshKey,
28 User,
29};
30
31/// Current Unix time in seconds, for `created_at` columns.
32pub(crate) fn now() -> i64 {
33 std::time::SystemTime::now()
34 .duration_since(std::time::UNIX_EPOCH)
35 .map(|d| d.as_secs() as i64)
36 .unwrap_or(0)
37}
38
39/// Shared application state: configuration plus a database handle.
40///
41/// Cloneable and cheap to pass around — `toasty::Db` is internally reference
42/// counted and backed by a connection pool.
43#[derive(Clone)]
44pub struct App {
45 pub config: Config,
46 pub db: toasty::Db,
47}
48
49impl App {
50 /// Initialize application state from a config: ensure the data directories
51 /// exist, then open the database and create the schema.
52 pub async fn bootstrap(config: Config) -> Result<Self> {
53 std::fs::create_dir_all(&config.data_dir)?;
54 std::fs::create_dir_all(config.repositories_dir())?;
55
56 let db = db::connect(config.database_path()).await?;
57
58 Ok(Self { config, db })
59 }
60}