TextureSync/server/texture-sync-server/src/server_state.rs

143 lines
4.5 KiB
Rust
Raw Normal View History

2019-04-20 01:24:19 +02:00
use crate::model::*;
2019-05-05 20:28:35 +02:00
use crate::persistency::*;
2019-04-20 01:24:19 +02:00
use crate::protocol::*;
use crate::search::*;
2019-04-20 01:24:19 +02:00
2019-05-05 20:28:35 +02:00
use std::path::Path;
use std::sync::*;
2019-04-20 01:24:19 +02:00
2019-04-24 17:01:43 +02:00
#[derive(Clone)]
2019-04-20 01:24:19 +02:00
pub struct ServerState {
2019-05-05 20:28:35 +02:00
data_store: Arc<RwLock<DataStore>>,
}
impl ServerState {
#[allow(dead_code)]
2019-05-05 20:28:35 +02:00
pub fn new(storage_path: &Path) -> std::io::Result<Self> {
Ok(Self {
data_store: Arc::new(RwLock::new(DataStore::new(&storage_path)?)),
})
}
2019-04-20 01:24:19 +02:00
}
impl ProtocolHandler for ServerState {
fn query(&mut self, query: &[String]) -> ProtocolResult<Vec<Texture>> {
let q = Query::parse(query)
.map_err(|e| ProtocolError::BadRequest(format!("Invalid Query String: {:?}", e)))?;
let data_store = self.data_store.read().unwrap();
let mut textures = data_store.borrow_textures();
Ok(q.search(&mut textures))
2019-04-20 01:24:19 +02:00
}
2019-04-24 19:24:00 +02:00
fn get_texture_by_id(&mut self, id: &str) -> ProtocolResult<Option<Texture>> {
2019-05-05 20:28:35 +02:00
let data_store = self.data_store.read().unwrap();
Ok(data_store.texture_by_id(id))
2019-04-20 01:24:19 +02:00
}
2019-04-24 19:24:00 +02:00
fn get_texture_by_name(&mut self, name: &str) -> ProtocolResult<Option<Texture>> {
2019-05-05 20:28:35 +02:00
let data_store = self.data_store.read().unwrap();
Ok(data_store.texture_by_name(name))
2019-04-20 01:24:19 +02:00
}
2019-04-24 19:24:00 +02:00
fn get_texture_file(&mut self, hash: Sha256) -> ProtocolResult<Vec<u8>> {
2019-05-05 20:28:35 +02:00
let data_store = self.data_store.read().unwrap();
let data = data_store.read_texture_file_by_hash(&hash)?;
Ok(data)
2019-04-20 01:24:19 +02:00
}
2019-04-24 19:24:00 +02:00
fn get_texture_preview(
&mut self,
hash: Sha256,
format: TextureFormat,
) -> ProtocolResult<Vec<u8>> {
2019-05-05 20:28:35 +02:00
let mut data_store = self.data_store.write().unwrap();
match data_store.get_texture_preview(&hash, format) {
Ok(data) => Ok(data),
Err(TextureFileError::NotFound) => Err(ProtocolError::FileNotFound(
"Texture not found!".to_string(),
)),
Err(TextureFileError::ImageError(_)) => Err(ProtocolError::FileNotFound(
"Didn't Find valid Texture File".to_string(),
)),
Err(TextureFileError::IoError(err)) => Err(ProtocolError::InternalServerError(err)),
}
2019-04-20 01:24:19 +02:00
}
fn replace_texture(
&mut self,
delete: Option<Texture>,
insert: Option<Texture>,
insert_texture_data: Option<Vec<u8>>,
) -> ProtocolResult<ReplaceTextureStatus> {
2019-05-05 20:28:35 +02:00
let mut data_store = self.data_store.write().unwrap();
match insert_texture_data {
Some(data) => {
data_store.store_texture_file(&data)?;
}
None => (),
}
match (delete, insert) {
(Some(delete), Some(insert)) => {
if !data_store.is_texture_file_on_disk(&insert.texture_hash) {
return Ok(ReplaceTextureStatus::NeedTextureData(insert.texture_hash));
}
if !data_store.delete(&delete) {
return Err(ProtocolError::Conflict(
"Delete Texture was modified!".to_string(),
));
}
if !data_store.insert(insert) {
// undo delete
// panics if texture file is delete during delete and reinsert.
// unlikely to happen.
assert!(data_store.insert(delete));
return Err(ProtocolError::Conflict(
"Name or Id already taken.".to_string(),
));
}
2019-05-06 09:34:12 +02:00
data_store.flush_metadata()?;
2019-05-05 20:28:35 +02:00
Ok(ReplaceTextureStatus::Ok)
}
(Some(delete), None) => {
if !data_store.delete(&delete) {
return Err(ProtocolError::Conflict(
"Delete Texture was modified!".to_string(),
));
}
2019-05-06 09:34:12 +02:00
data_store.flush_metadata()?;
2019-05-05 20:28:35 +02:00
Ok(ReplaceTextureStatus::Ok)
}
(None, Some(insert)) => {
if !data_store.is_texture_file_on_disk(&insert.texture_hash) {
return Ok(ReplaceTextureStatus::NeedTextureData(insert.texture_hash));
}
if !data_store.insert(insert) {
// undo delete
return Err(ProtocolError::Conflict(
"Name or Id already taken.".to_string(),
));
}
2019-05-06 09:34:12 +02:00
data_store.flush_metadata()?;
2019-05-05 20:28:35 +02:00
Ok(ReplaceTextureStatus::Ok)
}
(None, None) => Ok(ReplaceTextureStatus::Ok),
}
2019-04-20 01:24:19 +02:00
}
}