initial commit
This commit is contained in:
commit
a88e0e3bbb
6 changed files with 3109 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
2983
Cargo.lock
generated
Normal file
2983
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "multiiverse"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-web = "4.13.0"
|
||||||
|
dotenvy = "0.15.7"
|
||||||
|
log = "0.4.29"
|
||||||
|
quick-xml = { version = "0.39.3", features = ["serialize"] }
|
||||||
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
|
sqlx = { version = "0.8.6", features = ["runtime-tokio", "tls-native-tls", "postgres", "chrono", "ipnetwork"] }
|
||||||
54
src/discovery/mod.rs
Normal file
54
src/discovery/mod.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
sync::{Arc, LazyLock},
|
||||||
|
};
|
||||||
|
|
||||||
|
use actix_web::{Responder, get, web};
|
||||||
|
use serde::Serialize;
|
||||||
|
use sqlx::PgPool;
|
||||||
|
|
||||||
|
use crate::xml::Xml;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Endpoint {
|
||||||
|
host: &'static str,
|
||||||
|
api_host: &'static str,
|
||||||
|
portal_host: &'static str,
|
||||||
|
n3ds_host: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(rename = "result")]
|
||||||
|
struct Result {
|
||||||
|
has_error: u32,
|
||||||
|
version: u32,
|
||||||
|
endpoint: Endpoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
static HOST_ENDPOINT: LazyLock<String> =
|
||||||
|
LazyLock::new(|| env::var("HOST_ENDPOINT").expect("host endpoint address was not set"));
|
||||||
|
|
||||||
|
static API_HOST_ENDPOINT: LazyLock<String> =
|
||||||
|
LazyLock::new(|| env::var("API_HOST_ENDPOINT").expect("api host endpoint address was not set"));
|
||||||
|
|
||||||
|
static PORTAL_HOST_ENDPOINT: LazyLock<String> = LazyLock::new(|| {
|
||||||
|
env::var("PORTAL_HOST_ENDPOINT").expect("portal host endpoint address was not set")
|
||||||
|
});
|
||||||
|
|
||||||
|
static N3DS_HOST_ENDPOINT: LazyLock<String> = LazyLock::new(|| {
|
||||||
|
env::var("N3DS_HOST_ENDPOINT").expect("n3ds host endpoint address was not set")
|
||||||
|
});
|
||||||
|
|
||||||
|
#[get("/v1/endpoint")]
|
||||||
|
pub async fn discovery(_pool: web::Data<Arc<PgPool>>) -> impl Responder {
|
||||||
|
Xml(Result {
|
||||||
|
has_error: 0,
|
||||||
|
version: 1,
|
||||||
|
endpoint: Endpoint {
|
||||||
|
host: &HOST_ENDPOINT,
|
||||||
|
api_host: &API_HOST_ENDPOINT,
|
||||||
|
portal_host: &PORTAL_HOST_ENDPOINT,
|
||||||
|
n3ds_host: &N3DS_HOST_ENDPOINT,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
30
src/main.rs
Normal file
30
src/main.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
use std::{env, sync::Arc};
|
||||||
|
|
||||||
|
use actix_web::{App, HttpServer, web};
|
||||||
|
use dotenvy::dotenv;
|
||||||
|
use sqlx::postgres::PgPoolOptions;
|
||||||
|
mod discovery;
|
||||||
|
mod xml;
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
dotenv().ok();
|
||||||
|
|
||||||
|
let act_database_url = env::var("DATABASE_URL").expect("account database url is not set");
|
||||||
|
|
||||||
|
let pool = Arc::new(
|
||||||
|
PgPoolOptions::new()
|
||||||
|
.max_connections(5)
|
||||||
|
.connect(&act_database_url)
|
||||||
|
.await
|
||||||
|
.expect("unable to create pool"),
|
||||||
|
);
|
||||||
|
HttpServer::new(move || {
|
||||||
|
App::new()
|
||||||
|
.app_data(web::Data::new(pool.clone()))
|
||||||
|
.service(discovery::discovery)
|
||||||
|
})
|
||||||
|
.bind(("127.0.0.1", 8080))?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
||||||
29
src/xml.rs
Normal file
29
src/xml.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use std::result;
|
||||||
|
|
||||||
|
use actix_web::{HttpResponse, HttpResponseBuilder, Responder, body::BoxBody, http::StatusCode};
|
||||||
|
use log::error;
|
||||||
|
use quick_xml::{SeError, se::Serializer};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
pub fn serialize_with_version(serializable: &impl Serialize) -> result::Result<String, SeError> {
|
||||||
|
let mut write_dest = "<?xml version=\"1.0\"?>".to_owned();
|
||||||
|
|
||||||
|
serializable.serialize(Serializer::new(&mut write_dest))?;
|
||||||
|
Ok(write_dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Xml<T: Serialize>(pub T);
|
||||||
|
|
||||||
|
impl<T: Serialize> Responder for Xml<T> {
|
||||||
|
type Body = BoxBody;
|
||||||
|
|
||||||
|
fn respond_to(self, _req: &actix_web::HttpRequest) -> HttpResponse<Self::Body> {
|
||||||
|
match serialize_with_version(&self.0) {
|
||||||
|
Ok(o) => HttpResponseBuilder::new(StatusCode::OK).body(o),
|
||||||
|
Err(e) => {
|
||||||
|
error!("error whilest serializing xml: {}", e);
|
||||||
|
HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue