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