aboutsummaryrefslogtreecommitdiff
path: root/src/classes/pptr.rs
blob: d6e4bb6fabe28ce5dc4440815d31c5664b734f5f (plain)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use super::HValue;
use crate::object::{Value, parser::FromValue};
use anyhow::{Result, anyhow, bail};
use serde::Serialize;
use std::marker::PhantomData;

#[derive(Debug, Serialize)]
pub struct PPtr<T = HValue> {
    #[serde(skip, default)]
    _class: PhantomData<T>,
    pub class: String,
    pub file_id: i32,
    pub path_id: i64,
}

impl<T> FromValue for PPtr<T> {
    fn from_value(v: Value) -> Result<Self> {
        let Value::Object { class, fields } = v else {
            bail!("PPtr expected but not an object")
        };
        let inner = class
            .strip_prefix("PPtr<")
            .ok_or(anyhow!("not a PPtr"))?
            .strip_suffix(">")
            .ok_or(anyhow!("PPtr '>' missing"))?;
        Ok(PPtr {
            class: inner.to_owned(),
            _class: PhantomData,
            file_id: fields["m_FileID"]
                .as_i32()
                .ok_or(anyhow!("PPtr m_FileID is not i32"))?,
            path_id: fields["m_PathID"]
                .as_i64()
                .ok_or(anyhow!("PPtr m_FileID is not i64"))?,
        })
    }
}

impl PPtr {
    pub fn cast<T>(self) -> PPtr<T> {
        PPtr {
            _class: PhantomData,
            class: self.class,
            file_id: self.file_id,
            path_id: self.path_id,
        }
    }
}