feat: dependency system

This commit is contained in:
Ahmet Kaan GÜMÜŞ 2024-11-20 00:16:31 +03:00
parent e5e3bf2de5
commit cee3d10759
3 changed files with 53 additions and 70 deletions

View file

@ -1,8 +1,9 @@
use std::fmt::Display; use std::fmt::Display;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha3::{Digest, Sha3_512};
use surrealdb::sql::Datetime; use surrealdb::sql::Datetime;
use tokio::fs::File; use tokio::{fs::File, io::AsyncReadExt};
use tokio_util::io::ReaderStream; use tokio_util::io::ReaderStream;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -11,7 +12,8 @@ pub struct Package {
publisher: Publisher, publisher: Publisher,
version: Version, version: Version,
size: u64, size: u64,
hash: String, hash: Vec<u8>,
dependencies: Vec<String>,
publish_date_time: Datetime, publish_date_time: Datetime,
last_update_date_time: Datetime, last_update_date_time: Datetime,
location: String, location: String,
@ -24,40 +26,18 @@ impl Package {
publisher, publisher,
version, version,
size: 0, size: 0,
hash: String::default(), hash: vec![],
dependencies: vec![],
publish_date_time: Datetime::default(), publish_date_time: Datetime::default(),
last_update_date_time: Datetime::default(), last_update_date_time: Datetime::default(),
location: String::new(), location: String::new(),
} }
} }
pub fn get_name(&self) -> String { pub fn get_name(&self) -> String {
self.name.to_string() self.name.to_string()
} }
fn get_publisher_name(&self) -> String {
self.publisher.get_name()
}
fn get_version(&self) -> String {
self.version.to_string()
}
fn get_size(&self) -> u64 {
self.size
}
fn get_hash(&self) -> String {
self.hash.to_string()
}
fn get_publish_date_time(&self) -> String {
self.publish_date_time.to_string()
}
fn get_last_update_date_time(&self) -> String {
self.last_update_date_time.to_string()
}
pub fn get_location(&self) -> String { pub fn get_location(&self) -> String {
self.location.to_string() self.location.to_string()
} }
@ -68,9 +48,29 @@ impl Package {
Err(_) => None, Err(_) => None,
} }
} }
pub fn set_location(&mut self, location: &String) { pub fn set_location(&mut self, location: &String) {
self.location = location.to_owned() self.location = location.to_owned()
} }
pub fn get_dependencies(&self) -> &[String] {
self.dependencies.as_slice()
}
pub fn set_last_update_date_time(&mut self) {
self.last_update_date_time = Datetime::default();
}
pub async fn set_hash(&mut self) {
if let Ok(mut package_file) = File::open(self.get_location()).await {
let mut hasher = Sha3_512::new();
let mut data_buffer = vec![];
if let Ok(_) = package_file.read_to_end(&mut data_buffer).await {
hasher.update(data_buffer);
self.hash = hasher.finalize().to_vec();
}
}
}
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -80,23 +80,6 @@ pub struct Version {
third: u8, third: u8,
} }
impl Version {
fn new(first: u8, second: u8, third: u8) -> Self {
Version {
first,
second,
third,
}
}
fn update(&mut self, first: u8, second: u8, third: u8) -> &Self {
self.first = first;
self.second = second;
self.third = third;
self
}
}
impl Display for Version { impl Display for Version {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}.{}", self.first, self.second, self.third) write!(f, "{}.{}.{}", self.first, self.second, self.third)
@ -107,18 +90,3 @@ impl Display for Version {
pub struct Publisher { pub struct Publisher {
name: String, name: String,
} }
impl Publisher {
fn new(name: String) -> Self {
Publisher { name }
}
fn get_name(&self) -> String {
self.name.clone()
}
fn update(&mut self, name: String) -> &Self {
self.name = name;
self
}
}

View file

@ -1,3 +1,5 @@
use std::path::PathBuf;
use axum::extract::Multipart; use axum::extract::Multipart;
use tokio::{fs::File, io::AsyncWriteExt}; use tokio::{fs::File, io::AsyncWriteExt};
use tokio_util::io::ReaderStream; use tokio_util::io::ReaderStream;
@ -15,8 +17,11 @@ pub async fn read_package(package_name: String) -> Option<Package> {
database::read_package(package_name).await database::read_package(package_name).await
} }
pub async fn update_package(package_name: String, package: routing::Package) -> Option<Package> { pub async fn update_package(package_name: String, mut package: Package) -> Option<Package> {
let package = Package::new(package.name, package.publisher, package.version); for dependency in package.get_dependencies() {
database::read_package(dependency.to_string()).await?;
}
package.set_last_update_date_time();
database::update_package(package_name, package).await database::update_package(package_name, package).await
} }
@ -39,13 +44,21 @@ pub async fn upload_package(mut package_file: Multipart) -> Option<Package> {
if let Some(package_file_name) = package_file_part.file_name() { if let Some(package_file_name) = package_file_part.file_name() {
let package_file_name = package_file_name.to_owned(); let package_file_name = package_file_name.to_owned();
let file_location = format!("./{}/{}", PACKAGE_PATH, package_file_name); let file_location = format!("./{}/{}", PACKAGE_PATH, package_file_name);
if let Ok(file_location) = PathBuf::from(file_location).canonicalize() {
if let Some(file_location) = file_location.to_str() {
if let Ok(package_file_data) = package_file_part.bytes().await { if let Ok(package_file_data) = package_file_part.bytes().await {
if let Some(mut package) = if let Some(mut package) =
crate::package::utils::read_package(package_file_name.to_owned()).await crate::package::utils::read_package(package_file_name.to_owned())
.await
{ {
if let Ok(mut file_descriptor) = File::create_new(&file_location).await { if let Ok(mut file_descriptor) =
if let Ok(_) = file_descriptor.write_all(&package_file_data).await { File::create_new(&file_location).await
package.set_location(&file_location); {
if let Ok(_) =
file_descriptor.write_all(&package_file_data).await
{
package.set_location(&file_location.to_string());
package.set_hash().await;
return Some(package); return Some(package);
} }
} }
@ -54,5 +67,7 @@ pub async fn upload_package(mut package_file: Multipart) -> Option<Package> {
} }
} }
} }
}
}
None None
} }

View file

@ -64,7 +64,7 @@ async fn read_package(Path(package_name): Path<String>) -> impl IntoResponse {
async fn update_package( async fn update_package(
Path(package_name): Path<String>, Path(package_name): Path<String>,
Json(package): Json<Package>, Json(package): Json<crate::package::package::Package>,
) -> impl IntoResponse { ) -> impl IntoResponse {
match crate::package::utils::update_package(package_name, package).await { match crate::package::utils::update_package(package_name, package).await {
Some(package) => (StatusCode::ACCEPTED, Json(serde_json::json!(package))), Some(package) => (StatusCode::ACCEPTED, Json(serde_json::json!(package))),