ft_sdk/
lib.rs

1//! This crate can only be used when compiling to wasm, and wasm is run by
2//! [www.fifthtry.com](https://www.fifthtry.com), or by [`fastn`](https://fastn.com), the command
3//! line tool to use help developers build FifthTry Apps or when self-hosting FifthTry Apps.
4#![forbid(unsafe_code)]
5#![deny(unused_extern_crates)]
6#![cfg_attr(feature = "field-extractors", feature(adt_const_params))]
7#![cfg_attr(feature = "field-extractors", feature(unsized_const_params))]
8#![cfg_attr(feature = "field-extractors", allow(incomplete_features))]
9
10extern crate self as ft_sdk;
11
12pub mod auth;
13pub mod chr;
14mod crypto;
15pub mod data;
16mod error;
17pub mod form;
18pub mod from_request;
19pub mod processor;
20mod rng;
21pub mod schema;
22pub mod session;
23pub mod utils;
24mod uuid;
25
26pub use anyhow::{Context, Error, anyhow, bail, ensure};
27pub use auth::UserId;
28pub use crypto::{DecryptionError, EncryptedString, PlainText};
29pub use error::{SpecialError, not_found_, server_error_, single_error, unauthorised_};
30#[cfg(feature = "field-extractors")]
31pub use from_request::{AppUrl, Cookie, Default, Hidden, Optional, Query, Required};
32pub use from_request::{
33    Config, Form, FromRequest, Host, Json, MainPackage, Path, Scheme, WasmPackage,
34    WrappedFromRequest,
35};
36pub use ft_derive::{data, form, processor, wrapped_processor};
37#[cfg(feature = "postgres")]
38pub use ft_sys::PgConnection;
39pub use ft_sys::{ConnectionError, UserData, email, env, http, println};
40#[cfg(feature = "sqlite")]
41pub use ft_sys::{Sqlite, SqliteConnection};
42pub use ft_sys_shared::{
43    CancelEmailError, Email, EmailAddress, EmailContent, EmailHandle, RenderedEmail, SendEmailError,
44};
45pub use rng::Rng;
46pub use session::{SessionData, SessionID};
47pub use uuid::{uuid, uuid_without_dashes};
48
49pub type FrontendData = std::collections::HashMap<String, serde_json::Value>;
50pub type FormError = std::collections::HashMap<String, String>;
51pub type Result<T> = std::result::Result<T, Error>;
52
53#[cfg(all(feature = "sqlite-default", feature = "postgres-default"))]
54compile_error!("Both sqlite and postgres features are enabled. Only one should be enabled.");
55
56#[cfg(feature = "sqlite-default")]
57pub type Connection = SqliteConnection;
58
59#[cfg(feature = "postgres-default")]
60pub type Connection = PgConnection;
61
62#[cfg(any(feature = "sqlite-default", feature = "postgres-default"))]
63pub fn default_connection() -> std::result::Result<Connection, ConnectionError> {
64    #[cfg(feature = "sqlite-default")]
65    {
66        default_sqlite()
67    }
68
69    #[cfg(feature = "postgres-default")]
70    {
71        default_pg()
72    }
73}
74
75/// Get a connection to the default postgres database.
76#[cfg(feature = "postgres")]
77pub fn default_pg() -> std::result::Result<PgConnection, ConnectionError> {
78    PgConnection::connect("default")
79}
80
81/// Get a connection to the default sqlite database.
82///
83/// Most FifthTry Apps should use this function to get the default connection.
84#[cfg(feature = "sqlite")]
85pub fn default_sqlite() -> std::result::Result<SqliteConnection, ConnectionError> {
86    let db = ft_sys::env::var("DB_FILE".to_string());
87    let db_url = db.unwrap_or_else(|| "default".to_string());
88
89    SqliteConnection::connect(db_url.as_str())
90}
91
92pub(crate) fn json<T: serde::Serialize>(
93    t: T,
94) -> std::result::Result<::http::Response<bytes::Bytes>, ft_sdk::Error> {
95    let d = match serde_json::to_string(&t) {
96        Ok(d) => d,
97        Err(e) => {
98            return Ok(::http::Response::builder()
99                .status(500)
100                .body(format!("json-error: {e:?}\n").into())?);
101        }
102    };
103
104    Ok(::http::Response::builder()
105        .status(200)
106        .header("Content-Type", "application/json")
107        .body(d.into())?)
108}