Merge branch 'master' of git.mosad.xyz:localhorst/TextureSync

This commit is contained in:
Hendrik Schutter 2019-04-30 20:53:08 +02:00
commit cd8a3218d5
4 changed files with 113 additions and 17 deletions

View File

@ -1,20 +1,29 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[derive(Clone, Debug, Deserialize, Serialize, Eq, Hash, PartialEq)]
pub struct Sha256(#[serde(serialize_with = "as_hex", deserialize_with = "from_hex")] pub [u8; 32]);
fn hash_to_hex_string(hash: &[u8; 32]) -> String {
use std::fmt::*;
let mut hex_string = String::with_capacity(64);
for digit in hash.iter() {
write!(hex_string, "{:02X}", digit).unwrap();
}
hex_string
}
impl Sha256 {
pub fn create_hex_string(&self) -> String {
hash_to_hex_string(&self.0)
}
}
fn as_hex<S>(hash: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use std::fmt::*;
let mut hex_string = String::new();
for digit in hash {
write!(hex_string, "{:02X}", digit).unwrap();
}
serializer.serialize_str(&hex_string)
serializer.serialize_str(&hash_to_hex_string(hash))
}
fn from_hex<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>

View File

@ -1,6 +1,6 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[derive(Clone, Debug, Deserialize, Serialize, Eq, Hash, PartialEq)]
pub enum TextureFormat {
#[serde(rename = "png")]
PNG,

View File

@ -0,0 +1,18 @@
use crate::model::Texture;
use serde::{Deserialize, Serialize};
use std::fs;
use std::io;
use std::path::Path;
#[derive(Deserialize, Serialize)]
struct CollectionFile {
textures: Vec<Texture>,
}
pub fn load_collection_file(path: &Path) -> io::Result<Vec<Texture>> {
let file = fs::File::open(path)?;
let buf_reader = io::BufReader::new(file);
let collection: CollectionFile = serde_json::from_reader(buf_reader)?;
Ok(collection.textures)
}

View File

@ -6,11 +6,13 @@
use crate::model::*;
use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::sync::Arc;
pub use self::search::Query;
mod collection_file;
mod image_convert;
mod search;
@ -31,7 +33,15 @@ pub struct DataStore {
impl DataStore {
pub fn new(path: &Path) -> io::Result<DataStore> {
unimplemented!()
let base_path = path.to_path_buf();
let mut collection_file_path = base_path.clone();
collection_file_path.push("collection.json");
Ok(DataStore {
data_dir: base_path,
texture: collection_file::load_collection_file(&collection_file_path)?,
preview_cache: HashMap::new(),
})
}
pub fn garbage_collect(&mut self) -> io::Result<()> {
@ -45,27 +55,86 @@ impl DataStore {
/// returns true if successful
pub fn delete(&mut self, tex: &Texture) -> bool {
unimplemented!();
// Find the texture
let pos = self.texture.iter().position(|e| e == tex);
match pos {
// Remove it
Some(idx) => {
let removed = self.texture.remove(idx);
let key = (removed.format, removed.texture_hash);
self.preview_cache.remove(&key);
true
}
// Texture not found
None => false,
}
}
pub fn insert(&mut self, tex: Texture) -> bool {
unimplemented!();
// Check for collisions
let pos = self
.texture
.iter()
.position(|e| e.id == tex.id || e.name == tex.name);
match pos {
// Texture with same name or id is already stored
Some(_) => false,
// Insert it
None => {
self.texture.push(tex);
true
}
}
}
pub fn by_name<'a>(&'a self, name: &str) -> Option<&'a Texture> {
unimplemented!();
let pos = self.texture.iter().position(|e| e.name == name);
match pos {
Some(idx) => Some(self.texture.get(idx).unwrap()),
None => None,
}
}
pub fn by_id<'a, 'b>(&'a self, id: &'b str) -> Option<&'a Texture> {
unimplemented!();
let pos = self.texture.iter().position(|e| e.id == id);
match pos {
Some(idx) => Some(self.texture.get(idx).unwrap()),
None => None,
}
}
pub fn has_hash(&self, hash: &Sha256) -> bool {
unimplemented!();
// TODO What is the purpose of this function?
// Currently checks for textures in the list with the given hash.
// Should it check for an existing image file instead?
self.texture
.iter()
.position(|e| &e.texture_hash == hash)
.is_some()
}
pub fn get_texture_file(&mut self, hash: &Sha256) -> TextureFileResult {
unimplemented!();
use io::Read;
let mut file_path = self.data_dir.clone();
file_path.push("textures");
file_path.push(hash.create_hex_string().to_lowercase());
let mut file = match fs::File::open(file_path) {
Ok(f) => f,
Err(e) => {
if e.kind() == io::ErrorKind::NotFound {
return Err(TextureFileError::NotFound);
} else {
return Err(TextureFileError::IoError(e));
}
}
};
let mut buffer = Vec::new();
match file.read_to_end(&mut buffer) {
Ok(_) => (),
Err(e) => return Err(TextureFileError::IoError(e)),
};
Ok(Arc::new(buffer))
}
pub fn get_texture_preview(&mut self, hash: &Sha256) -> TextureFileResult {