Implement ID tracking, start dumping ideas into rbx_session

This commit is contained in:
Lucien Greathouse 2018-04-04 18:27:05 -07:00
parent bb451bc4e9
commit 8d87d81f49
3 changed files with 149 additions and 0 deletions

View file

@ -8,6 +8,8 @@ extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate regex; extern crate regex;
pub mod rbx_session;
pub mod id;
pub mod web; pub mod web;
pub mod core; pub mod core;
pub mod project; pub mod project;

21
server/src/id.rs Normal file
View file

@ -0,0 +1,21 @@
use std::sync::atomic::{AtomicUsize, Ordering};
/// A unique identifier, not guaranteed to be generated in any order.
pub type Id = usize;
lazy_static! {
static ref LAST_ID: AtomicUsize = AtomicUsize::new(0);
}
/// Generate a new ID, which has no defined ordering.
pub fn get_id() -> Id {
LAST_ID.fetch_add(1, Ordering::SeqCst)
}
#[test]
fn it_gives_unique_numbers() {
let a = get_id();
let b = get_id();
assert!(a != b);
}

126
server/src/rbx_session.rs Normal file
View file

@ -0,0 +1,126 @@
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use std::io::Read;
use std::fs::{self, File};
use id::{Id};
#[derive(Debug, Clone)]
struct FileRoute {
partition: String,
route: Vec<String>,
}
impl FileRoute {
pub fn to_path_buf(&self, partition_path: &Path) -> PathBuf {
let mut result = partition_path.to_path_buf();
for route_piece in &self.route {
result.push(route_piece);
}
result
}
pub fn extended_with(&self, pieces: &[&str]) -> FileRoute {
let mut result = self.clone();
for piece in pieces {
result.route.push(piece.to_string());
}
result
}
}
enum FileItem {
File {
contents: String,
},
Directory {
children: HashMap<String, FileItem>,
},
}
struct RbxInstance {
parent: Option<Id>,
}
struct RbxSession {
partitions_path: HashMap<String, PathBuf>,
partition_instances: HashMap<String, Id>,
}
impl RbxSession {
fn load(&self) {
for (partition_name, partition_path) in &self.partitions_path {
}
}
fn read(&self, route: &FileRoute) -> Result<FileItem, ()> {
let partition_path = self.partitions_path.get(&route.partition)
.ok_or(())?;
let path = route.to_path_buf(partition_path);
let metadata = fs::metadata(path)
.map_err(|_| ())?;
if metadata.is_dir() {
self.read_directory(route)
} else if metadata.is_file() {
self.read_file(route)
} else {
Err(())
}
}
fn read_file(&self, route: &FileRoute) -> Result<FileItem, ()> {
let partition_path = self.partitions_path.get(&route.partition)
.ok_or(())?;
let path = route.to_path_buf(partition_path);
let mut file = File::open(path)
.map_err(|_| ())?;
let mut contents = String::new();
file.read_to_string(&mut contents)
.map_err(|_| ())?;
Ok(FileItem::File {
contents,
})
}
fn read_directory(&self, route: &FileRoute) -> Result<FileItem, ()> {
let partition_path = self.partitions_path.get(&route.partition)
.ok_or(())?;
let path = route.to_path_buf(partition_path);
let reader = fs::read_dir(path)
.map_err(|_| ())?;
let mut children = HashMap::new();
for entry in reader {
let entry = entry
.map_err(|_| ())?;
let path = entry.path();
let name = path.file_name().unwrap().to_string_lossy().into_owned();
let child_route = route.extended_with(&[&name]);
match self.read(&child_route) {
Ok(child_item) => {
children.insert(name, child_item);
},
Err(_) => {},
}
}
Ok(FileItem::Directory {
children,
})
}
}