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