Skip to main content

headless_lms_server/
lib.rs

1/*!
2The server that handles the requests.
3
4## See also
5
6* [headless_lms_utils]
7* [headless_lms_models]
8*/
9
10pub mod config;
11pub mod controllers;
12pub mod domain;
13pub mod openapi;
14pub mod prelude;
15
16#[cfg(test)]
17mod env_guard;
18pub mod programs;
19#[cfg(test)]
20pub mod test_helper;
21
22#[macro_use]
23extern crate tracing;
24
25#[macro_use]
26extern crate doc_macro;
27
28use crate::config::FileStoreRuntimeConfig;
29pub use headless_lms_base::tracing::setup_tracing;
30use headless_lms_utils::file_store::{
31    FileStore, google_cloud_file_store::GoogleCloudFileStore, local_file_store::LocalFileStore,
32};
33use oauth2::{EndpointNotSet, EndpointSet};
34use std::sync::Arc;
35
36pub type OAuthClient = oauth2::basic::BasicClient<
37    EndpointSet,
38    EndpointNotSet,
39    EndpointNotSet,
40    EndpointNotSet,
41    EndpointSet,
42>;
43
44/**
45Setups file store so that it can be passed to actix web as data.
46Using Arc here so that this can be accessed from all the different worker threads.
47*/
48pub async fn setup_file_store(
49    file_store_config: &FileStoreRuntimeConfig,
50    base_url: &str,
51) -> Arc<dyn FileStore + Send + Sync> {
52    if file_store_config.use_google_cloud_storage {
53        info!("Using Google Cloud Storage as the file store");
54        let bucket_name = file_store_config
55            .google_cloud_storage_bucket_name
56            .clone()
57            .expect("GOOGLE_CLOUD_STORAGE_BUCKET_NAME missing from runtime config");
58        Arc::new(
59            GoogleCloudFileStore::new(bucket_name)
60                .await
61                .expect("Failed to initialize file store"),
62        )
63    } else {
64        info!("Using local file storage as the file store");
65        let normalized_base_url = base_url.trim_end_matches('/');
66        Arc::new(
67            LocalFileStore::new(
68                "uploads".into(),
69                format!("{normalized_base_url}/api/v0/files/uploads/"),
70            )
71            .expect("Failed to initialize file store"),
72        )
73    }
74}
75
76/// Includes the type's generated docs as a string.
77/// generated by doc-file-generator as a string.
78/// Used with the helper macro from the doc-macro crate: #[generated_doc]
79#[macro_export]
80macro_rules! generated_docs {
81    ($t: expr_2021, ts) => {
82        concat!(
83            "## Response TypeScript definition\n",
84            "```ts\n",
85            include_str!(concat!(
86                env!("CARGO_MANIFEST_DIR"),
87                "/generated-docs/",
88                stringify!($t),
89                ".ts"
90            )),
91            "\n```\n",
92        )
93    };
94    ($t: expr_2021, json) => {
95        concat!(
96            "## Example response\n",
97            "```json\n",
98            include_str!(concat!(
99                env!("CARGO_MANIFEST_DIR"),
100                "/generated-docs/",
101                stringify!($t),
102                ".json"
103            )),
104            "\n```\n",
105        )
106    };
107    ($t: expr_2021) => {
108        generated_docs!($t, json)
109    };
110}