partialy implement Glue Logic
This commit is contained in:
parent
5369304516
commit
28085f9b87
@ -40,6 +40,10 @@ pub enum ProtocolError {
|
|||||||
|
|
||||||
impl From<io::Error> for ProtocolError {
|
impl From<io::Error> for ProtocolError {
|
||||||
fn from(err: io::Error) -> Self {
|
fn from(err: io::Error) -> Self {
|
||||||
|
if err.kind() == io::ErrorKind::NotFound {
|
||||||
|
ProtocolError::FileNotFound("File Not Found!".to_string())
|
||||||
|
} else {
|
||||||
ProtocolError::InternalServerError(err)
|
ProtocolError::InternalServerError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@ mod image_convert;
|
|||||||
mod metadata_file;
|
mod metadata_file;
|
||||||
mod search;
|
mod search;
|
||||||
|
|
||||||
pub type TextureFileResult = Result<Arc<Vec<u8>>, TextureFileError>;
|
pub type TextureFileResult = Result<Vec<u8>, TextureFileError>;
|
||||||
pub enum TextureFileError {
|
pub enum TextureFileError {
|
||||||
NotFound,
|
NotFound,
|
||||||
IoError(io::Error),
|
IoError(io::Error),
|
||||||
@ -39,7 +39,7 @@ pub struct DataStore {
|
|||||||
id_index: HashMap<String, Texture>,
|
id_index: HashMap<String, Texture>,
|
||||||
name_index: HashMap<String, Texture>,
|
name_index: HashMap<String, Texture>,
|
||||||
|
|
||||||
preview_cache: HashMap<(TextureFormat, Sha256), Arc<Vec<u8>>>,
|
preview_cache: HashMap<(TextureFormat, Sha256), Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataStore {
|
impl DataStore {
|
||||||
@ -75,7 +75,7 @@ impl DataStore {
|
|||||||
let metadata_file = metadata_file::MetadataFile::load(base_dir)?;
|
let metadata_file = metadata_file::MetadataFile::load(base_dir)?;
|
||||||
|
|
||||||
for texture in metadata_file.textures.iter() {
|
for texture in metadata_file.textures.iter() {
|
||||||
match store.insert(texture.clone())? {
|
match store.insert(texture.clone()) {
|
||||||
true => (),
|
true => (),
|
||||||
false => {
|
false => {
|
||||||
panic!("inserting {:#?} failed !!!", texture); // TODO: What should be done?
|
panic!("inserting {:#?} failed !!!", texture); // TODO: What should be done?
|
||||||
@ -94,17 +94,17 @@ impl DataStore {
|
|||||||
self.name_index.get(id).cloned()
|
self.name_index.get(id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, texture: Texture) -> io::Result<bool> {
|
pub fn insert(&mut self, texture: Texture) -> bool {
|
||||||
if self.id_index.contains_key(&texture.id) {
|
if self.id_index.contains_key(&texture.id) {
|
||||||
return Ok(false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.name_index.contains_key(&texture.name) {
|
if self.name_index.contains_key(&texture.name) {
|
||||||
return Ok(false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.is_texture_file_on_disk(&texture.texture_hash)? {
|
if !self.is_texture_file_on_disk(&texture.texture_hash) {
|
||||||
return Ok(false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.id_index.insert(texture.id.clone(), texture.clone());
|
self.id_index.insert(texture.id.clone(), texture.clone());
|
||||||
@ -112,7 +112,7 @@ impl DataStore {
|
|||||||
.insert(texture.name.clone(), texture.clone());
|
.insert(texture.name.clone(), texture.clone());
|
||||||
self.textures.insert(texture.clone());
|
self.textures.insert(texture.clone());
|
||||||
|
|
||||||
Ok(true)
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns true if successful
|
/// returns true if successful
|
||||||
@ -132,28 +132,23 @@ impl DataStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the texture, given by hash, physically exists on the file system.
|
/// Check if the texture, given by hash, physically exists on the file system.
|
||||||
pub fn is_texture_file_on_disk(&self, hash: &Sha256) -> io::Result<bool> {
|
pub fn is_texture_file_on_disk(&self, hash: &Sha256) -> bool {
|
||||||
let file_path = self.texture_file_path(&hash);
|
let file_path = self.texture_file_path(&hash);
|
||||||
|
|
||||||
Ok(file_path.is_file())
|
file_path.is_file()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: this return type looks wrong : ImageError can't happen
|
pub fn read_texture_file_by_hash(&self, hash: &Sha256) -> io::Result<Vec<u8>> {
|
||||||
pub fn read_texture_file_by_hash(&mut self, hash: &Sha256) -> TextureFileResult {
|
|
||||||
use std::fs::*;
|
use std::fs::*;
|
||||||
use std::io::*;
|
use std::io::*;
|
||||||
|
|
||||||
if !(self.is_texture_file_on_disk(&hash)?) {
|
|
||||||
return Err(TextureFileError::NotFound);
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_path = self.texture_file_path(&hash);
|
let file_path = self.texture_file_path(&hash);
|
||||||
|
|
||||||
let mut file = File::open(file_path)?;
|
let mut file = File::open(file_path)?;
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
file.read_to_end(&mut buffer)?;
|
file.read_to_end(&mut buffer)?;
|
||||||
|
|
||||||
Ok(Arc::new(buffer))
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store_texture_file(&mut self, data: &[u8]) -> io::Result<()> {
|
pub fn store_texture_file(&mut self, data: &[u8]) -> io::Result<()> {
|
||||||
|
@ -4,13 +4,23 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::model::*;
|
use crate::model::*;
|
||||||
|
use crate::persistency::*;
|
||||||
use crate::protocol::*;
|
use crate::protocol::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::path::Path;
|
||||||
|
use std::sync::*;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ServerState {
|
pub struct ServerState {
|
||||||
// ...
|
data_store: Arc<RwLock<DataStore>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServerState {
|
||||||
|
pub fn new(storage_path: &Path) -> std::io::Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
data_store: Arc::new(RwLock::new(DataStore::new(&storage_path)?)),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtocolHandler for ServerState {
|
impl ProtocolHandler for ServerState {
|
||||||
@ -19,15 +29,21 @@ impl ProtocolHandler for ServerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_by_id(&mut self, id: &str) -> ProtocolResult<Option<Texture>> {
|
fn get_texture_by_id(&mut self, id: &str) -> ProtocolResult<Option<Texture>> {
|
||||||
unimplemented!()
|
let data_store = self.data_store.read().unwrap();
|
||||||
|
Ok(data_store.texture_by_id(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_by_name(&mut self, name: &str) -> ProtocolResult<Option<Texture>> {
|
fn get_texture_by_name(&mut self, name: &str) -> ProtocolResult<Option<Texture>> {
|
||||||
unimplemented!()
|
let data_store = self.data_store.read().unwrap();
|
||||||
|
Ok(data_store.texture_by_name(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_file(&mut self, hash: Sha256) -> ProtocolResult<Vec<u8>> {
|
fn get_texture_file(&mut self, hash: Sha256) -> ProtocolResult<Vec<u8>> {
|
||||||
unimplemented!()
|
let data_store = self.data_store.read().unwrap();
|
||||||
|
|
||||||
|
let data = data_store.read_texture_file_by_hash(&hash)?;
|
||||||
|
|
||||||
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_texture_preview(
|
fn get_texture_preview(
|
||||||
@ -35,7 +51,18 @@ impl ProtocolHandler for ServerState {
|
|||||||
hash: Sha256,
|
hash: Sha256,
|
||||||
format: TextureFormat,
|
format: TextureFormat,
|
||||||
) -> ProtocolResult<Vec<u8>> {
|
) -> ProtocolResult<Vec<u8>> {
|
||||||
unimplemented!()
|
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)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_texture(
|
fn replace_texture(
|
||||||
@ -44,7 +71,63 @@ impl ProtocolHandler for ServerState {
|
|||||||
insert: Option<Texture>,
|
insert: Option<Texture>,
|
||||||
insert_texture_data: Option<Vec<u8>>,
|
insert_texture_data: Option<Vec<u8>>,
|
||||||
) -> ProtocolResult<ReplaceTextureStatus> {
|
) -> ProtocolResult<ReplaceTextureStatus> {
|
||||||
// NOTE: must also check if insert_texture_data fits sha256!
|
let mut data_store = self.data_store.write().unwrap();
|
||||||
unimplemented!()
|
|
||||||
|
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(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ReplaceTextureStatus::Ok)
|
||||||
|
}
|
||||||
|
(Some(delete), None) => {
|
||||||
|
if !data_store.delete(&delete) {
|
||||||
|
return Err(ProtocolError::Conflict(
|
||||||
|
"Delete Texture was modified!".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ReplaceTextureStatus::Ok)
|
||||||
|
}
|
||||||
|
(None, None) => Ok(ReplaceTextureStatus::Ok),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user