summaryrefslogtreecommitdiff
path: root/rust_backend
diff options
context:
space:
mode:
Diffstat (limited to 'rust_backend')
-rw-r--r--rust_backend/.vscode/launch.json45
-rw-r--r--rust_backend/Cargo.toml18
-rw-r--r--rust_backend/src/eve_api.rs319
-rw-r--r--rust_backend/src/eve_service.rs42
-rw-r--r--rust_backend/src/main.rs95
-rw-r--r--rust_backend/src/manager.rs90
-rw-r--r--rust_backend/src/market/mod.rs3
-rw-r--r--rust_backend/src/market/order.rs83
-rw-r--r--rust_backend/src/market/trade.rs63
-rw-r--r--rust_backend/src/pathfinding/graph.rs7
-rw-r--r--rust_backend/src/pathfinding/mod.rs15
-rw-r--r--rust_backend/src/pathfinding/models.rs86
-rw-r--r--rust_backend/src/pathfinding/parser.rs46
-rw-r--r--rust_backend/src/route.rs108
14 files changed, 0 insertions, 1020 deletions
diff --git a/rust_backend/.vscode/launch.json b/rust_backend/.vscode/launch.json
deleted file mode 100644
index cf1efa1..0000000
--- a/rust_backend/.vscode/launch.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "type": "lldb",
- "request": "launch",
- "name": "Debug executable 'rust_backend'",
- "cargo": {
- "args": [
- "build",
- "--bin=rust_backend",
- "--package=rust_backend"
- ],
- "filter": {
- "name": "rust_backend",
- "kind": "bin"
- }
- },
- "args": [],
- "cwd": "${workspaceFolder}"
- },
- {
- "type": "lldb",
- "request": "launch",
- "name": "Debug unit tests in executable 'rust_backend'",
- "cargo": {
- "args": [
- "test",
- "--no-run",
- "--bin=rust_backend",
- "--package=rust_backend"
- ],
- "filter": {
- "name": "rust_backend",
- "kind": "bin"
- }
- },
- "args": [],
- "cwd": "${workspaceFolder}"
- }
- ]
-} \ No newline at end of file
diff --git a/rust_backend/Cargo.toml b/rust_backend/Cargo.toml
deleted file mode 100644
index cace60d..0000000
--- a/rust_backend/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-name = "rust_backend"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-actix-web = "4"
-tokio = { version = "1", features = ["full"] }
-ctrlc = "3.2"
-serde = { version = "1.0", features = ["derive"] }
-serde_derive = "1.0"
-serde_json = "1.0"
-reqwest = { version = "0.11", features = ["json"] }
-dotenv = "*"
-chrono = { version = "0.4", features = ["serde"] }
-csv = "*" \ No newline at end of file
diff --git a/rust_backend/src/eve_api.rs b/rust_backend/src/eve_api.rs
deleted file mode 100644
index 18e1007..0000000
--- a/rust_backend/src/eve_api.rs
+++ /dev/null
@@ -1,319 +0,0 @@
-use dotenv::dotenv;
-use std::env;
-use std::error::Error;
-use std::fs::{self, File};
-use std::io::{self, Read, Write};
-use std::path::Path;
-use std::time::{SystemTime, UNIX_EPOCH, Duration};
-use std::sync::Arc;
-
-use chrono::{DateTime, Utc};
-use serde::{Deserialize, Serialize};
-use tokio::{task, time};
-use tokio::sync::Semaphore;
-
-
-use crate::pathfinding::Location;
-use crate::market::Order;
-
-const TOKEN_FILE: &str = "token.json";
-
-use std::sync::Mutex;
-
-
-#[derive(Deserialize, Serialize, Clone)]
-struct TokenData {
- access_token: String,
- refresh_token: String,
- expires_at: u64,
-}
-
-#[derive(Deserialize)]
-struct TokenResponse {
- access_token: String,
- refresh_token: String,
- expires_in: u64,
-}
-
-pub struct EveApiClient {
- client_id: String,
- client_secret: String,
- character_id: String,
- redirect_url: String,
- access_token: Mutex<Option<String>>,
- expires_at: Mutex<Option<u64>>,
-}
-
-
-impl EveApiClient {
- pub fn new() -> Result<Self, Box<dyn Error>> {
- dotenv().ok();
-
- let client_id = env::var("CLIENT_ID").map_err(|e| format!("CLIENT_ID error: {}", e))?;
- let client_secret = env::var("CLIENT_SECRET").map_err(|e| format!("CLIENT_SECRET error: {}", e))?;
- let character_id = env::var("CHARACTER_ID").map_err(|e| format!("CHARACTER_ID error: {}", e))?;
- let redirect_url = env::var("REDIRECT_URL").map_err(|e| format!("REDIRECT_URL error: {}", e))?;
-
- let token_data = match Self::load_token_from_file() {
- Ok(data) => Some(data),
- Err(_) => None,
- };
-
- Ok(EveApiClient {
- client_id,
- client_secret,
- character_id,
- redirect_url,
- access_token: Mutex::new(token_data.clone().map(|data| data.access_token)),
- expires_at: Mutex::new(token_data.map(|data| data.expires_at)),
- })
- }
-
- pub fn get_authorization_url(&self) -> String {
- let auth_url = format!(
- "https://login.eveonline.com/v2/oauth/authorize/?response_type=code&client_id={}&redirect_uri={}&scope={}",
- self.client_id,
- self.redirect_url,
- "esi-assets.read_assets.v1 esi-location.read_location.v1 esi-location.read_online.v1 esi-ui.open_window.v1 esi-ui.write_waypoint.v1".replace(" ", "%20")
- );
- auth_url
- }
-
- pub async fn exchange_code_for_token(&self, code: &str) -> Result<(), Box<dyn Error>> {
- let client = reqwest::Client::new();
- let res = client
- .post("https://login.eveonline.com/v2/oauth/token")
- .form(&[
- ("client_id", self.client_id.as_str()),
- ("client_secret", self.client_secret.as_str()),
- ("code", code),
- ("redirect_uri", self.redirect_url.as_str()),
- ("grant_type", "authorization_code"),
- ])
- .send()
- .await;
-
- let res = match res {
- Ok(response) => response,
- Err(e) => return Err(Box::new(e)),
- };
-
- let token_response: TokenResponse = match res.json().await {
- Ok(data) => data,
- Err(e) => return Err(Box::new(e)),
- };
-
- let expires_at = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .expect("Time went backwards") // Handle this error as per your need
- .as_secs() + token_response.expires_in;
-
- let token_data = TokenData {
- access_token: token_response.access_token,
- refresh_token: token_response.refresh_token,
- expires_at,
- };
-
- if let Err(e) = Self::save_token_to_file(&token_data) {
- return Err(e);
- }
-
- let mut token = self.access_token.lock().unwrap();
- *token = Some(token_data.access_token);
-
- Ok(())
- }
-
- pub async fn refresh_access_token(&self) -> Result<(), Box<dyn Error>> {
- let token_data = match Self::load_token_from_file() {
- Ok(data) => data,
- Err(_) => return Err("Failed to load token data".into()),
- };
-
-
- let client = reqwest::Client::new();
- let res = client
- .post("https://login.eveonline.com/v2/oauth/token") // Replace with the actual token endpoint
- .form(&[
- ("client_id", self.client_id.as_str()),
- ("client_secret", self.client_secret.as_str()),
- ("refresh_token", token_data.refresh_token.as_str()),
- ("grant_type", "refresh_token"),
- ])
- .send()
- .await?;
-
- let refreshed_token_response: TokenResponse = res.json().await?;
-
- let current_timestamp = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .expect("Time went backwards")
- .as_secs();
-
- let new_expires_at = current_timestamp + refreshed_token_response.expires_in;
-
- let new_token_data = TokenData {
- access_token: refreshed_token_response.access_token,
- refresh_token: refreshed_token_response.refresh_token,
- expires_at: new_expires_at,
- };
-
- Self::save_token_to_file(&new_token_data)?;
-
- let mut access_token = self.access_token.lock().unwrap();
- *access_token = Some(new_token_data.access_token);
- let mut expires_at = self.expires_at.lock().unwrap();
- *expires_at = Some(new_expires_at);
-
- Ok(())
- }
-
-
- pub async fn request_location(&self) -> Result<Location, Box<dyn Error>> {
- self.ensure_valid_token().await?;
-
- let url = format!("https://esi.evetech.net/latest/characters/{}/location/", self.character_id);
-
- println!("{:?}", url);
-
- let client = reqwest::Client::new();
-
- let response = client.get(url)
- .bearer_auth(self.get_access_token().unwrap())
- .send()
- .await?;
-
- println!("{:?}", response);
-
- if response.status().is_success() {
- let data = response.json::<Location>().await?;
- Ok(data)
- } else {
- Err(Box::new(response.error_for_status().unwrap_err()))
- }
- }
-
- pub async fn request_order_metadata(&self, region: u64) -> Result<(u64, DateTime<Utc>), Box<dyn Error>> {
- let url = format!("https://esi.evetech.net/latest/markets/{}/orders/?datasource=tranquility&order_type=all&page=1", region);
-
- let client = reqwest::Client::new();
- let response = client.get(&url)
- .send()
- .await
- .map_err(|e| e.to_string())?;
-
- let x_pages = match response.headers().get("x-pages") {
- Some(x_pages_value) => {
- match x_pages_value.to_str() {
- Ok(value_str) => {
- match value_str.parse::<u64>() {
- Ok(value) => value,
- Err(_) => return Err("Failed to parse x-pages value into u64".into()),
- }
- }
- Err(_) => return Err("Invalid x-pages header value".into()),
- }
- }
- None => return Err("X-Pages header not found".into()),
- };
-
- let expiry_unix_time = match response.headers().get("expires") {
- Some(expiry_value) => {
- match expiry_value.to_str() {
- Ok(value_str) => {
- match DateTime::parse_from_rfc2822(value_str) {
- Ok(expiry_date) => expiry_date.with_timezone(&Utc),
- Err(_) => return Err("Failed to parse expiry date".into()),
- }
- }
- Err(_) => return Err("Invalid expiry header value".into()),
- }
- }
- None => return Err("Expires header not found".into()),
- };
-
- Ok((x_pages, expiry_unix_time))
- }
-
-
-
- pub async fn request_orders(&self, region: u64) -> Result<(Vec<Order>, DateTime<Utc>), Box<dyn Error>> {
- let (x_pages, expiry) = self.request_order_metadata(region).await?;
-
- let client = reqwest::Client::builder()
- .timeout(Duration::from_secs(30))
- .build()?;
-
- let semaphore = Arc::new(Semaphore::new(10));
- let mut tasks = Vec::new();
-
- for page in 1..=x_pages {
- let permit = semaphore.clone().acquire_owned().await?;
- let client = client.clone();
- let url = format!("https://esi.evetech.net/latest/markets/{}/orders/?datasource=tranquility&order_type=all&page={}", region, page);
-
- let task = task::spawn(async move {
- time::sleep(Duration::from_millis(20)).await;
- let response = client.get(&url).send().await?;
- println!("{:?}", &url);
- drop(permit);
- response.error_for_status()?.json::<Vec<Order>>().await
- });
-
- tasks.push(task);
- }
-
- let mut orders = Vec::new();
- for task in tasks {
- match task.await {
- Ok(result) => match result {
- Ok(mut page_orders) => orders.append(&mut page_orders),
- Err(e) => return Err(Box::new(e)),
- },
- Err(e) => return Err(Box::new(e)),
- }
- }
-
- Ok((orders, expiry))
- }
-
- pub async fn ensure_valid_token(&self) -> Result<(), Box<dyn Error>> {
- let current_timestamp = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map_err(|e| format!("System time error: {}", e))?
- .as_secs();
-
- let should_refresh = {
- let expires_at = self.expires_at.lock().unwrap();
- let expires_at_value = expires_at.unwrap_or(0);
- current_timestamp > expires_at_value
- };
-
- if should_refresh {
- self.refresh_access_token().await?;
- }
-
- Ok(())
- }
- pub fn get_access_token(&self) -> Option<String> {
- let token = self.access_token.lock().unwrap();
- token.clone()
- }
-
- pub fn save_token_to_file(token_data: &TokenData) -> Result<(), Box<dyn Error>> {
- let token_json = serde_json::to_string(token_data)?;
- fs::write(Path::new(TOKEN_FILE), token_json)?;
- Ok(())
- }
-
- fn load_token_from_file() -> Result<TokenData, Box<dyn Error>> {
- let token_json = match fs::read_to_string(Path::new(TOKEN_FILE)) {
- Ok(content) => content,
- Err(_) => return Err("Unable to read token file".into()),
- };
- let token_data: TokenData = serde_json::from_str(&token_json)?;
- Ok(token_data)
- }
-
-
-}
diff --git a/rust_backend/src/eve_service.rs b/rust_backend/src/eve_service.rs
deleted file mode 100644
index c831847..0000000
--- a/rust_backend/src/eve_service.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use crate::eve_api::EveApiClient;
-use crate::pathfinding::Location;
-use crate::market::Orders;
-
-use std::error::Error;
-
-pub struct EveService {
- client: EveApiClient,
-}
-
-impl EveService {
- pub fn new() -> Result<Self, Box<dyn Error>> {
- let eve_api_client = EveApiClient::new()?;
- Ok(EveService { client: eve_api_client, })
- }
-
- pub fn get_authorization_url(&self) -> String {
- self.client.get_authorization_url()
- }
-
- pub async fn exchange_code_for_token(&self, code: &str) -> Result<(), Box<dyn Error>> {
- self.client.exchange_code_for_token(code).await
- }
-
- pub async fn location(&self) -> Result<Location, Box<dyn Error>> {
- self.client.request_location().await.map_err(|e| e.into())
- }
-
- pub async fn updated_orders(&self, current_orders: &Orders) -> Result<Orders, Box<dyn Error>> {
- let mut region_orders = Orders::new();
-
- let regions = current_orders.expired_regions();
-
- for &region in regions.iter() {
- let (orders, expiry) = self.client.request_orders(region).await?;
- region_orders.insert(region, orders, expiry);
- }
-
- Ok(region_orders)
-
- }
-}
diff --git a/rust_backend/src/main.rs b/rust_backend/src/main.rs
deleted file mode 100644
index 4a2e086..0000000
--- a/rust_backend/src/main.rs
+++ /dev/null
@@ -1,95 +0,0 @@
-mod manager;
-mod eve_service;
-mod eve_api;
-mod pathfinding;
-mod market;
-
-use manager::Manager;
-
-use actix_web::{web, App, HttpServer, Responder, HttpResponse, http::header};
-use std::sync::Mutex;
-use tokio::sync::watch;
-use serde::Deserialize;
-
-
-async fn index() -> impl Responder {
- "Hi"
-}
-
-async fn location(manager: web::Data<Manager>) -> impl Responder {
- match manager.location() {
- Some(location) => {
- let station_id = location.station_id.map_or("None".to_string(), |id| id.to_string());
- let structure_id = location.structure_id.map_or("None".to_string(), |id| id.to_string());
- format!(
- "Current location: Solar System ID: {}, Station ID: {}, Structure ID: {}",
- location.solar_system_id, station_id, structure_id
- )
- },
- None => "No location available".to_string(),
- }
-}
-
-async fn orders(manager: web::Data<Manager>) -> impl Responder {
- let orders = manager.orders();
- HttpResponse::Ok().json(orders)
-}
-
-async fn start_oauth(manager: web::Data<Manager>) -> HttpResponse {
- let auth_url = manager.get_authorization_url();
- HttpResponse::Found()
- .append_header((header::LOCATION, auth_url.as_str()))
- .finish()
-}
-
-#[derive(Deserialize)]
-struct AuthCode {
- code: String,
-}
-
-async fn oauth_callback(
- query: web::Query<AuthCode>,
- manager: web::Data<Manager>,
-) -> HttpResponse {
- match manager.exchange_code_for_token(&query.code).await {
- Ok(_) => HttpResponse::Ok().body("Token exchange successful"),
- Err(e) => HttpResponse::InternalServerError().body(format!("Error: {}", e)),
- }
-}
-
-#[actix_web::main]
-async fn main() -> std::io::Result<()> {
- let manager = web::Data::new(Manager::new());
-
-
- let manager_clone = manager.clone();
- let (shutdown_tx, shutdown_rx) = watch::channel(false);
-
- let manager_handle = tokio::spawn(async move {
- manager_clone.run(shutdown_rx).await;
- });
-
- let server = HttpServer::new(move || {
- App::new()
- .app_data(manager.clone())
- .route("/", web::get().to(index))
- .route("/location", web::get().to(location))
- .route("/orders", web::get().to(orders))
- .route("/start_oauth", web::get().to(start_oauth))
- .route("/oauth_callback", web::get().to(oauth_callback))
- })
- .bind("127.0.0.1:8080")?
- .run();
-
- ctrlc::set_handler(move || {
- let _ = shutdown_tx.send(true);
- })
- .expect("Error setting Ctrl-C handler");
-
- tokio::select! {
- _ = server => {},
- _ = manager_handle => {},
- }
-
- Ok(())
-}
diff --git a/rust_backend/src/manager.rs b/rust_backend/src/manager.rs
deleted file mode 100644
index b9cbe08..0000000
--- a/rust_backend/src/manager.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-use std::sync::Mutex;
-use tokio::sync::watch;
-
-use std::error::Error;
-
-use crate::eve_service::EveService;
-use crate::pathfinding::{Location, build};
-use crate::market::{Order, Orders};
-
-pub struct Manager {
- // route_state: Mutex<Route>
- // route_info_state: Mutex<RouteInfo>
- orders_state: Mutex<Orders>,
- location: Mutex<Option<Location>>,
- // log_state: Mutex<Log>
- eve_service: EveService,
-
-}
-
-impl Manager {
- pub fn new() -> Manager {
-
- build();
-
- Manager {
- location: Mutex::new( None ),
- eve_service: EveService::new().expect("Manager to generate EveService"),
- orders_state: Mutex::new( Orders::new() ),
- }
-
- }
-
- pub async fn run(&self, shutdown_signal: watch::Receiver<bool>) {
- loop {
- tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
- if *shutdown_signal.borrow() {
- println!("Manager task is shutting down.");
- break;
- }
-
- match self.eve_service.location().await {
- Ok(result) => {
- match self.location.lock() {
- Ok(mut location) => *location = Some(result),
- Err(e) => eprintln!("Error locking location mutex: {}", e),
- }
- }
- Err(e) => {
- eprintln!("Error fetching location {}", e);
- }
- }
-
-
- let orders_clone = match self.orders_state.lock() {
- Ok(orders_lock) => orders_lock.clone(),
- Err(e) => {
- eprintln!("Error locking orders_state mutex: {}", e);
- continue;
- }
- };
-
- match self.eve_service.updated_orders(&orders_clone).await {
- Ok(updated_orders) => {
- match self.orders_state.lock() {
- Ok(mut orders_state) => orders_state.update(updated_orders),
- Err(e) => eprintln!("Error locking orders_state mutex: {}", e),
- }
- }
- Err(e) => eprintln!("Error updating orders: {}", e),
- }
- }
- }
- pub fn get_authorization_url(&self) -> String {
- self.eve_service.get_authorization_url()
- }
-
- pub async fn exchange_code_for_token(&self, code: &str) -> Result<(), Box<dyn Error>> {
- self.eve_service.exchange_code_for_token(code).await
- }
-
- pub fn location(&self) -> Option<Location> {
- let location = self.location.lock().unwrap();
- location.clone()
- }
-
- pub fn orders(&self) -> Vec<Order> {
- let orders = self.orders_state.lock().unwrap();
- orders.orders()
- }
-} \ No newline at end of file
diff --git a/rust_backend/src/market/mod.rs b/rust_backend/src/market/mod.rs
deleted file mode 100644
index 16d1f37..0000000
--- a/rust_backend/src/market/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod order;
-
-pub use order::{Order, Orders}; \ No newline at end of file
diff --git a/rust_backend/src/market/order.rs b/rust_backend/src/market/order.rs
deleted file mode 100644
index 6dbbcf6..0000000
--- a/rust_backend/src/market/order.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-use std::error::Error;
-use std::collections::HashMap;
-
-use chrono::{DateTime, Utc};
-use serde::{Deserialize, Serialize};
-
-use crate::eve_service::EveService;
-
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct Order {
- duration: u64,
- is_buy_order: bool,
- issued: DateTime<Utc>,
- location_id: u64,
- min_volume: u64,
- order_id: u64,
- price: f64,
- range: String,
- system_id: u64,
- type_id: u64,
- volume_remain: u64,
- volume_total: u64
-}
-
-const REGIONS: [u64; 1] = [10000033];
-
-#[derive(Clone, Serialize)]
-pub struct Orders {
- region_orders: HashMap<u64, Vec<Order>>,
- expiry_times: HashMap<u64, DateTime<Utc>>, // region_id to expiration time
-}
-
-
-impl Orders {
- pub fn new() -> Self {
- Orders {
- region_orders: HashMap::new(),
- expiry_times: HashMap::new(),
- }
- }
-
- pub fn insert(&mut self, region: u64, orders: Vec<Order>, expiry: DateTime<Utc>) {
- self.region_orders.insert(region, orders);
- self.expiry_times.insert(region, expiry);
- }
-
- pub fn expired_regions(&self) -> Vec<u64> {
- let current_time = Utc::now();
-
- println!("expiry: {:?}, time now: {:?}", &self.expiry_times, &current_time);
-
- let mut expired: Vec<u64> = self.expiry_times.iter()
- .filter(|&(_region_id, &expiry_time)| expiry_time < current_time)
- .map(|(&region_id, _)| region_id)
- .collect();
-
- for &region in REGIONS.iter() {
- if !self.expiry_times.contains_key(&region) {
- expired.push(region);
- }
- }
-
-
- expired
-
- }
-
- pub fn update(&mut self, updated_orders: Orders) {
- for (key, value) in updated_orders.region_orders {
- self.region_orders.insert(key, value);
-
- if let Some(expiry_time) = updated_orders.expiry_times.get(&key) {
- self.expiry_times.insert(key, *expiry_time);
- }
- }
- }
-
-
- pub fn orders(&self) -> Vec<Order> {
- self.region_orders.values().flat_map(|orders| orders.clone()).collect()
- }
-} \ No newline at end of file
diff --git a/rust_backend/src/market/trade.rs b/rust_backend/src/market/trade.rs
deleted file mode 100644
index 362acbf..0000000
--- a/rust_backend/src/market/trade.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use crate::order::Order;
-
-pub struct Trade<'a> {
- from: &'a Order,
- to: &'a Order,
- quantity: usize,
- gross_profit: f64,
-}
-
-const TAX_RATE: f64 = 0.08
-
-impl<'a> Trade<'a> {
- pub fn new(from: &'a Order, to: &'a Order, quantity: usize) -> Self {
- Self { from, to, quantity }
- }
-
- pub fn create_trades(sell_orders: &'a [Order], buy_orders: &'a [Order]) -> Vec<Trade<'a>> {
- let mut trades: Vec<Trade<'a>> = Vec::new();
- let mut grouped_orders: HashMap<i32, (Vec<&'a Order>, Vec<&'a Order>)> = HashMap::new();
-
- // Grouping sell orders
- for order in sell_orders {
- grouped_orders.entry(order.type_id)
- .or_insert((Vec::new(), Vec::new()))
- .0
- .push(order);
- }
-
- // Grouping buy orders
- for order in buy_orders {
- grouped_orders.entry(order.type_id)
- .or_insert((Vec::new(), Vec::new()))
- .1
- .push(order);
- }
-
- // Iterating over each type_id's sell and buy orders to create trades
- for (_type_id, (sells, buys)) in grouped_orders {
- for &sell_order in sells {
- for &buy_order in buys {
- let quantity = std::cmp::min(sell_order.volume_remain, buy_order.volume_remain);
- let gross_profit = quantity as f64 * (buy_order.price * (1-TAX_RATE) - sell_order.price);
-
- if gross_profit <= 0.0 {
- continue;
- }
-
- let trade = Trade::new(
- sell_order,
- buy_order,
- quantity,
- gross_profit,
- );
-
- trades.push(trade);
- }
- }
- }
-
- trades
- }
-
-}
diff --git a/rust_backend/src/pathfinding/graph.rs b/rust_backend/src/pathfinding/graph.rs
deleted file mode 100644
index 0352007..0000000
--- a/rust_backend/src/pathfinding/graph.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use crate::pathfinding::models::{MapNode, Graph};
-
-use std::collections::HashMap;
-
-pub fn generate_graph(stations: &Vec<MapNode>) -> Graph {
- HashMap::new()
-} \ No newline at end of file
diff --git a/rust_backend/src/pathfinding/mod.rs b/rust_backend/src/pathfinding/mod.rs
deleted file mode 100644
index 32c2831..0000000
--- a/rust_backend/src/pathfinding/mod.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-mod models;
-mod parser;
-mod graph;
-pub use models::{Location, Graph};
-
-
-use crate::pathfinding::parser::parse_stations;
-use crate::pathfinding::graph::generate_graph;
-
-pub fn build() {
- let stations = parse_stations().unwrap();
- let gates_connnections = parse_gate_connections().unwrap()
- let graph = generate_graph(&stations, &gates_connnections);
-
-}
diff --git a/rust_backend/src/pathfinding/models.rs b/rust_backend/src/pathfinding/models.rs
deleted file mode 100644
index 4bbc580..0000000
--- a/rust_backend/src/pathfinding/models.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-use serde::{Deserialize, Deserializer, Serialize};
-use std::str::FromStr;
-use std::collections::HashMap;
-
-
-#[derive(Deserialize, Serialize, Clone)]
-pub struct Location {
- pub solar_system_id: i32,
- pub station_id: Option<i32>,
- pub structure_id: Option<i32>,
-}
-
-#[derive(Deserialize, Serialize, Clone, Debug)]
-pub struct RawNode {
- pub itemID: u64,
- pub typeID: u64,
- pub groupID: u64,
- #[serde(deserialize_with = "deserialize_optional_u64")]
- pub solarSystemID: Option<u64>,
- #[serde(deserialize_with = "deserialize_optional_u64")]
- pub constellationID: Option<u64>,
- #[serde(deserialize_with = "deserialize_optional_u64")]
- pub regionID: Option<u64>,
- #[serde(deserialize_with = "deserialize_optional_u64")]
- pub orbitID: Option<u64>,
- pub x: Option<f64>,
- pub y: Option<f64>,
- pub z: Option<f64>,
- #[serde(deserialize_with = "deserialize_optional_f64")]
- pub radius: Option<f64>,
- pub itemName: Option<String>,
- #[serde(deserialize_with = "deserialize_optional_f64")]
- pub security: Option<f64>,
-}
-
-
-fn deserialize_optional_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let s: Option<String> = Option::deserialize(deserializer)?;
- match s.as_deref() {
- Some("None") | Some("") => Ok(None), // Handle "None" and empty strings
- Some(str_val) => u64::from_str(str_val)
- .map(Some)
- .map_err(serde::de::Error::custom),
- None => Ok(None),
- }
-}
-
-fn deserialize_optional_f64<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
-where
- D: Deserializer<'de>,
-{
- let s: Option<String> = Option::deserialize(deserializer)?;
- match s.as_deref() {
- Some("None") | Some("") => Ok(None), // Handle "None" and empty strings
- Some(str_val) => str_val.parse::<f64>()
- .map(Some)
- .map_err(serde::de::Error::custom),
- None => Ok(None),
- }
-}
-
-#[derive(Debug)]
-pub struct MapNode {
- pub item_id: u64,
- pub is_station: bool,
- pub solar_system_id: u64,
- pub region_id: u64,
- pub x: f64,
- pub y: f64,
- pub z: f64,
- pub name: String,
- pub security: f64,
-}
-
-#[derive(Deserialize, Serialize, Clone, Debug)]
-pub struct Connection {
- stargate_id: u64,
- destination_id: u64,
-}
-
-
-
-pub type Graph = HashMap<u64, Vec<u64>>; \ No newline at end of file
diff --git a/rust_backend/src/pathfinding/parser.rs b/rust_backend/src/pathfinding/parser.rs
deleted file mode 100644
index 955a448..0000000
--- a/rust_backend/src/pathfinding/parser.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-use std::error::Error;
-use std::fs::File;
-use csv;
-
-use crate::pathfinding::models::{RawNode, MapNode};
-
-pub fn parse_stations() -> Result<Vec<MapNode>, Box<dyn Error>> {
- let file_path = "../mapDenormalize.csv";
- let file = File::open(file_path)?;
-
- let mut rdr = csv::Reader::from_reader(file);
-
- let mut raw_nodes: Vec<RawNode> = Vec::new();
- for result in rdr.deserialize() {
- match result {
- Ok(node) => raw_nodes.push(node),
- Err(e) => println!("Error deserializing record: {}", e),
- }
- }
-
- println!("raw nodes: {:?}", raw_nodes.len());
-
- let processed_nodes: Vec<MapNode> = raw_nodes.into_iter()
- .filter(|node| [15, 10].contains(&node.groupID))
- .map(|node| MapNode {
- item_id: node.itemID,
- is_station: node.groupID == 15,
- solar_system_id: node.solarSystemID.unwrap_or_default(),
- region_id: node.regionID.unwrap_or_default(),
- x: node.x.unwrap_or_default(),
- y: node.y.unwrap_or_default(),
- z: node.z.unwrap_or_default(),
- name: node.itemName.unwrap_or_default(),
- security: node.security.unwrap_or_default(),
- })
- .collect();
-
- println!("processed nodes: {:?}", processed_nodes.len());
-
-
- Ok(processed_nodes)
-}
-
-pub fn parse_gate_connections() -> Result<Vec<u64, u64>, Box<dyn Error>> {
- unimplemented!();
-} \ No newline at end of file
diff --git a/rust_backend/src/route.rs b/rust_backend/src/route.rs
deleted file mode 100644
index a2c477e..0000000
--- a/rust_backend/src/route.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-use std::collections::HashMap;
-
-struct Item {
- profit: f32,
- cost: f32,
- cargo: f32,
- quantity: usize,
-}
-
-#[derive(PartialEq, Eq, Hash, Clone)]
-struct DiscreteState {
- cost: isize,
- cargo: isize,
-}
-
-type StateMap = HashMap<DiscreteState, (f32, Vec<(usize, usize)>)>;
-
-fn discretize(value: f32, precision: f32) -> isize {
- (value / precision).round() as isize
-}
-
-fn knapsack(items: &[Item], max_cost: f32, max_cargo: f32) -> (f32, Vec<(usize, usize)>) {
- let mut best_state: StateMap = HashMap::new();
- let precision = 0.01; // Define the precision level for discretization
- best_state.insert(DiscreteState { cost: 0, cargo: 0 }, (0.0, vec![]));
-
- for (index, item) in items.iter().enumerate() {
- let mut new_state = best_state.clone();
-
- for (&DiscreteState { cost: current_cost, cargo: current_cargo }, &(current_profit, ref indices)) in &best_state {
- let max_quantity_cost = ((max_cost - current_cost as f32 * precision) / item.cost).floor() as usize;
- let max_quantity_cargo = ((max_cargo - current_cargo as f32 * precision) / item.cargo).floor() as usize;
-
- let quantity = *[
- item.quantity,
- max_quantity_cost,
- max_quantity_cargo,
- ]
- .iter()
- .min()
- .unwrap();
-
- if quantity == 0 {
- continue;
- }
-
- let total_cost = discretize(current_cost as f32 * precision + item.cost * (quantity as f32), precision);
- let total_cargo = discretize(current_cargo as f32 * precision + item.cargo * (quantity as f32), precision);
- let total_profit = current_profit + item.profit * (quantity as f32);
-
- let mut new_indices = indices.clone();
- new_indices.push((index, quantity));
-
- new_state
- .entry(DiscreteState { cost: total_cost, cargo: total_cargo })
- .and_modify(|(existing_profit, existing_indices)| {
- if *existing_profit < total_profit {
- *existing_profit = total_profit;
- *existing_indices = new_indices.clone();
- }
- })
- .or_insert((total_profit, new_indices));
- }
-
- best_state = new_state;
- }
-
- best_state.values().max_by(|&(p1, _), &(p2, _)| p1.partial_cmp(&p2).unwrap()).unwrap_or(&(0.0, vec![])).clone()
-}
-
-fn main() {
- // Example usage with some items defined
- let items = vec![
- Item {
- profit: 60.0,
- cost: 0.1,
- cargo: 0.2,
- quantity: 100,
- },
- Item {
- profit: 100.0,
- cost: 0.2,
- cargo: 0.5,
- quantity: 50,
- },
- Item {
- profit: 100.0,
- cost: 0.1,
- cargo: 0.5,
- quantity: 50,
- },
- Item {
- profit: 100.0,
- cost: 0.2,
- cargo: 0.3,
- quantity: 50,
- },
- ];
-
- let max_cost = 50.0;
- let max_cargo = 50.0;
-
- let (max_profit, item_selections) = knapsack(&items, max_cost, max_cargo);
- println!("Maximum profit: {}", max_profit);
- for (index, quantity) in item_selections {
- println!("Item {} taken with quantity: {}", index, quantity);
- }
-}