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