Current progress!

This commit is contained in:
Yu-Vitaqua-fer-Chronos 2023-12-10 23:10:46 +00:00
commit 85797beec3
8 changed files with 265 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

84
Cargo.lock generated Normal file
View File

@ -0,0 +1,84 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "supernovae"
version = "0.1.0"
dependencies = [
"ulid",
]
[[package]]
name = "ulid"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e37c4b6cbcc59a8dcd09a6429fbc7890286bcbb79215cea7b38a3c4c0921d93"
dependencies = [
"rand",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

9
Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "supernovae"
version = "0.1.0"
edition = "2021"
rust-version = "1.74.0"
license = "Apache-2.0"
[dependencies]
ulid = "1.1.0"

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Supernovae
A chat server written in Rust as a way to learn, and to hopefully build a
proof-of-concept federated and decentralised chat platform!

30
src/account.rs Normal file
View File

@ -0,0 +1,30 @@
use ulid::Ulid;
#[derive(Debug)]
pub enum Service {
Local,
GitHub
}
pub struct UserSource<'a> {
pub id: usize,
pub domain: &'a str,
pub authorised: bool,
pub banned: bool
}
#[derive(Debug)]
pub struct Login<'a> {
pub service: Service, // The service that the user is using for auth
pub service_user: &'a str, // User ID in the service provider
pub uid: Ulid // User's ID that the login belongs to
}
impl Service {
pub fn as_str(&self) -> &str {
match self {
Service::Local => "Local",
Service::GitHub => "GitHub"
}
}
}

7
src/main.rs Normal file
View File

@ -0,0 +1,7 @@
pub mod routes;
pub mod account;
pub mod semver;
fn main() {
println!("Hello, world!");
}

0
src/routes/mod.rs Normal file
View File

131
src/semver.rs Normal file
View File

@ -0,0 +1,131 @@
use std::fmt::Display;
const BITMASK_21_BITS: u32 = 0b111111111111111111111;
const BITMASK_22_BITS: u32 = 0b1111111111111111111111;
#[derive(Debug, PartialEq, Eq)]
pub enum SemVerError {
MajorTooLarge,
MinorTooLarge,
PatchTooLarge,
}
#[derive(Debug, PartialEq, Eq)]
pub struct SemVer(u64);
impl SemVer {
pub fn new(major: u32, minor: u32, patch: u32) -> Result<Self, SemVerError> {
if major > BITMASK_21_BITS {
return Err(SemVerError::MajorTooLarge);
} else if minor > BITMASK_21_BITS {
return Err(SemVerError::MinorTooLarge);
} else if patch > BITMASK_22_BITS {
return Err(SemVerError::PatchTooLarge);
}
let res: u64 = u64::from(major) << 43 | u64::from(minor) << 22 | u64::from(patch);
Ok(SemVer(res))
}
pub fn major(&self) -> u32 {
(self.0 >> 43) as u32
}
pub fn minor(&self) -> u32 {
((self.0 >> 22) & BITMASK_21_BITS as u64) as u32
}
pub fn patch(&self) -> u32 {
(self.0 & BITMASK_22_BITS as u64) as u32
}
pub fn set_major(&mut self, major: u32) -> Result<(), SemVerError> {
if major > BITMASK_21_BITS {
return Err(SemVerError::MajorTooLarge);
}
self.0 &= !(BITMASK_21_BITS as u64) << 43;
self.0 |= u64::from(major) << 43;
Ok(())
}
pub fn set_minor(&mut self, minor: u32) -> Result<(), SemVerError> {
if minor > BITMASK_21_BITS {
return Err(SemVerError::MinorTooLarge);
}
self.0 &= !(BITMASK_21_BITS as u64) << 22;
self.0 |= u64::from(minor) << 22;
Ok(())
}
pub fn set_patch(&mut self, patch: u32) -> Result<(), SemVerError> {
if patch > BITMASK_22_BITS {
return Err(SemVerError::PatchTooLarge);
}
self.0 &= !BITMASK_22_BITS as u64;
self.0 |= u64::from(patch);
Ok(())
}
}
impl Display for SemVer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}.{}.{}", self.major(), self.minor(), self.patch())
}
}
#[cfg(test)]
mod tests {
use super::*;
const SEMVER_1_2_3: SemVer = SemVer(8796101410819);
#[test]
fn validate_semver_eq() {
assert_eq!(SEMVER_1_2_3, SemVer::new(1, 2, 3).unwrap());
}
#[test]
fn validate_semver_ne() {
assert_ne!(SEMVER_1_2_3, SemVer::new(1, 2, 4).unwrap());
}
#[test]
fn validate_semver_errors() {
assert_eq!(SemVer::new(2097152, 2, 4).unwrap_err(), SemVerError::MajorTooLarge);
assert_eq!(SemVer::new(1, 2097152, 4).unwrap_err(), SemVerError::MinorTooLarge);
assert_eq!(SemVer::new(1, 2, 4194304).unwrap_err(), SemVerError::PatchTooLarge);
}
#[test]
fn validate_semver_valid() {
SemVer::new(2097151, 2, 4).unwrap();
SemVer::new(1, 2097151, 4).unwrap();
SemVer::new(1, 2, 4194303).unwrap();
}
#[test]
fn validate_semver_values() {
assert_eq!(SEMVER_1_2_3.major(), 1);
assert_eq!(SEMVER_1_2_3.minor(), 2);
assert_eq!(SEMVER_1_2_3.patch(), 3);
}
#[test]
fn validate_semver_set_values_valid() {
let mut semver = SEMVER_1_2_3;
semver.set_major(3).unwrap();
semver.set_minor(2).unwrap();
semver.set_patch(1).unwrap();
}
#[test]
fn validate_semver_set_values_errors() {
let mut semver = SEMVER_1_2_3;
assert_eq!(semver.set_major(2097152).unwrap_err(), SemVerError::MajorTooLarge);
assert_eq!(semver.set_minor(2097152).unwrap_err(), SemVerError::MinorTooLarge);
assert_eq!(semver.set_patch(4194304).unwrap_err(), SemVerError::PatchTooLarge);
}
}