gltf_v1_json/
camera.rs

1use std::fmt;
2
3use gltf_v1_derive::Validate;
4use serde::{de, ser};
5use serde_derive::{Deserialize, Serialize};
6
7use super::validation::Checked;
8
9#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
10pub struct Perspective {
11    #[serde(rename = "aspectRatio")]
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub aspect_ratio: Option<f32>,
14    pub yfov: f32,
15    pub zfar: f32,
16    pub znear: f32,
17}
18
19#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
20pub struct Orthographic {
21    pub xmag: f32,
22    pub ymag: f32,
23    pub zfar: f32,
24    pub znear: f32,
25}
26
27#[derive(Clone, Copy, Debug, Eq, PartialEq)]
28pub enum CameraType {
29    Perspective,
30    Orthographic,
31}
32
33impl CameraType {
34    pub const VALID_CAMERA_TYPES: &[&str] = &["perspective", "orthographic"];
35}
36
37impl TryFrom<&str> for CameraType {
38    type Error = ();
39
40    fn try_from(value: &str) -> Result<Self, Self::Error> {
41        match value {
42            "perspective" => Ok(CameraType::Perspective),
43            "orthographic" => Ok(CameraType::Orthographic),
44            _ => Err(()),
45        }
46    }
47}
48
49impl From<CameraType> for &str {
50    fn from(value: CameraType) -> Self {
51        match value {
52            CameraType::Perspective => "perspective",
53            CameraType::Orthographic => "orthographic",
54        }
55    }
56}
57
58impl ser::Serialize for CameraType {
59    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60    where
61        S: ser::Serializer,
62    {
63        serializer.serialize_str((*self).into())
64    }
65}
66
67impl<'de> de::Deserialize<'de> for Checked<CameraType> {
68    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
69    where
70        D: de::Deserializer<'de>,
71    {
72        struct Visitor;
73        impl de::Visitor<'_> for Visitor {
74            type Value = Checked<CameraType>;
75
76            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
77                write!(f, "any of: {:?}", CameraType::VALID_CAMERA_TYPES)
78            }
79
80            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
81            where
82                E: de::Error,
83            {
84                Ok(value
85                    .try_into()
86                    .map(Checked::Valid)
87                    .unwrap_or(Checked::Invalid))
88            }
89        }
90        deserializer.deserialize_str(Visitor)
91    }
92}
93
94#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
95pub struct Camera {
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub orthographic: Option<Orthographic>,
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub perspective: Option<Perspective>,
100    #[serde(rename = "type")]
101    pub type_: Checked<CameraType>,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub name: Option<String>,
104}
105
106#[test]
107fn test_camera_deserialize() {
108    let data = r#"{
109            "name" : "user-defined name of perspective camera",
110            "perspective" : {
111                "aspectRatio" : 1.77,
112                "yfov" : 0.7854,
113                "zfar" : 1000,
114                "znear" : 1
115            },
116            "type" : "perspective",
117            "extensions" : {
118               "extension_name" : {
119                  "extension specific" : "value"
120               }
121            },
122            "extras" : {
123                "Application specific" : "The extra object can contain any properties."
124            }
125        }"#;
126    let camera: Result<Camera, _> = serde_json::from_str(data);
127    let camera_unwrap = camera.unwrap();
128    println!("{}", serde_json::to_string(&camera_unwrap).unwrap());
129    assert_eq!(
130        Some("user-defined name of perspective camera".to_string()),
131        camera_unwrap.name
132    );
133}