implement serde (se, de) thingy for sha256, textureformat, texture
This commit is contained in:
		@ -6,6 +6,6 @@ edition = "2018"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
image = "0.21.1"
 | 
			
		||||
serde = "1.0.90"
 | 
			
		||||
serde = { version = "1.0.90", features = ["derive"] }
 | 
			
		||||
serde_json = "1.0.39"
 | 
			
		||||
lovecraft = "0.2.0"
 | 
			
		||||
@ -3,8 +3,13 @@
 | 
			
		||||
#![allow(unused_variables)]
 | 
			
		||||
#![allow(dead_code)]
 | 
			
		||||
 | 
			
		||||
pub struct Sha256(pub [u8; 64]);
 | 
			
		||||
mod sha256;
 | 
			
		||||
pub use sha256::Sha256;
 | 
			
		||||
 | 
			
		||||
mod texture_format;
 | 
			
		||||
pub use texture_format::TextureFormat;
 | 
			
		||||
 | 
			
		||||
#[derive(Eq, PartialEq, Clone, Serialize, Deserialize, Debug)]
 | 
			
		||||
pub struct Texture {
 | 
			
		||||
    pub id: String,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
@ -13,8 +18,3 @@ pub struct Texture {
 | 
			
		||||
    pub resolution: (usize, usize),
 | 
			
		||||
    pub texture_hash: Sha256,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub enum TextureFormat {
 | 
			
		||||
    PNG,
 | 
			
		||||
    JPEG,
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								server/texture-sync-server/src/model/sha256.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								server/texture-sync-server/src/model/sha256.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
 | 
			
		||||
pub struct Sha256(#[serde(serialize_with = "as_hex", deserialize_with = "from_hex")] [u8; 32]);
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn from_hex<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
 | 
			
		||||
where
 | 
			
		||||
    D: Deserializer<'de>,
 | 
			
		||||
{
 | 
			
		||||
    use serde::de::Error;
 | 
			
		||||
 | 
			
		||||
    fn hex2bytes(s: &str) -> Option<[u8; 32]> {
 | 
			
		||||
        if s.len() != 32 * 2 {
 | 
			
		||||
            return None; // String has wrong length
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut out = [0u8; 32];
 | 
			
		||||
        for (i, byte) in out.iter_mut().enumerate() {
 | 
			
		||||
            let string_index = i * 2;
 | 
			
		||||
            *byte = u8::from_str_radix(&s[string_index..=string_index + 1], 16).ok()?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Some(out);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String::deserialize(deserializer).and_then(|string| {
 | 
			
		||||
        hex2bytes(&string).ok_or_else(|| Error::custom("Invalid HEX String!".to_string()))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use serde_json;
 | 
			
		||||
 | 
			
		||||
    const HASH_BYTES: [u8; 32] = [
 | 
			
		||||
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
 | 
			
		||||
        25, 26, 27, 28, 29, 30, 31,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const HASH_STRING: &'static str =
 | 
			
		||||
        r#""000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F""#;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn serialize() {
 | 
			
		||||
        let hash = serde_json::to_string_pretty(&Sha256(HASH_BYTES)).unwrap();
 | 
			
		||||
        assert_eq!(&hash, HASH_STRING);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn deserialize() {
 | 
			
		||||
        let hash: Sha256 = serde_json::from_str(HASH_STRING).unwrap();
 | 
			
		||||
        assert_eq!(hash, Sha256(HASH_BYTES))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn fail_deserialize() {
 | 
			
		||||
        // too short.
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            serde_json::from_str::<'_, Sha256>(r#""0102013""#).is_err(),
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
        // wrong radix
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            serde_json::from_str::<'_, Sha256>(r#""Hallo Welt""#).is_err(),
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
        // too long.
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            serde_json::from_str::<'_, Sha256>( r#""000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F""#).is_err(),
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								server/texture-sync-server/src/model/texture_format.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								server/texture-sync-server/src/model/texture_format.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
			
		||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
 | 
			
		||||
pub enum TextureFormat {
 | 
			
		||||
    #[serde(rename = "png")]
 | 
			
		||||
    PNG,
 | 
			
		||||
    #[serde(rename = "jpeg")]
 | 
			
		||||
    JPEG,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    // Lol, I thought we would need custom code, like for Sha256, but it works out of the box :D
 | 
			
		||||
    // Anyhow, left the Test in.
 | 
			
		||||
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use serde_json;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn serialize() {
 | 
			
		||||
        let format = serde_json::to_string_pretty(&TextureFormat::PNG).unwrap();
 | 
			
		||||
        assert_eq!(&format, r#""png""#);
 | 
			
		||||
 | 
			
		||||
        let format = serde_json::to_string_pretty(&TextureFormat::JPEG).unwrap();
 | 
			
		||||
        assert_eq!(&format, r#""jpeg""#);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn deserialize() {
 | 
			
		||||
        let format: TextureFormat = serde_json::from_str(r#""png""#).unwrap();
 | 
			
		||||
        assert_eq!(format, TextureFormat::PNG);
 | 
			
		||||
 | 
			
		||||
        let format: TextureFormat = serde_json::from_str(r#""jpeg""#).unwrap();
 | 
			
		||||
        assert_eq!(format, TextureFormat::JPEG);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn fail_deserialize() {
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            serde_json::from_str::<'_, TextureFormat>(r#""notafmt""#).is_err(),
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Format must be lowercase!
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            serde_json::from_str::<'_, TextureFormat>(r#""PNG""#).is_err(),
 | 
			
		||||
            true
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user