Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deserializing toml::Value error #816

Open
HadziqM opened this issue Dec 2, 2024 · 4 comments
Open

deserializing toml::Value error #816

HadziqM opened this issue Dec 2, 2024 · 4 comments
Labels
A-serde Area: Serde integration C-enhancement Category: Raise on the bar on expectations

Comments

@HadziqM
Copy link

HadziqM commented Dec 2, 2024

i cant deserialize toml::Value into struct

fn get() -> Self {
        let file = format!("{}.toml", Self::name());
        if let Ok(x) = std::fs::read_to_string(SYSDIR.config_dir(file.clone())) {
            println!("de data succes: {:?}", toml::from_str::<Self>(&x).unwrap());
            if let Ok(mut data) = toml::from_str::<toml::Value>(&x) {
                // for pattern in Self::locate().to_string().split('.') {
                //     if let toml::Value::Table(table) = data {
                //         data = table.get(pattern).expect("invalid table name").clone();
                //     }
                // }
                println!("{:?}", data);
                data.try_into().expect("invalid deserialize data")
            }
        }
        panic!("{} not found", SYSDIR.config_dir(file));
    }
running 1 test
de data succes: GithubUpdate { repo: "ship-rework", owner: "HadziqM", token: None }
Table({"owner": String("HadziqM"), "repo": String("ship-rework")})
thread 'test::setting' panicked at lib-common/src/lib.rs:32:33:
invalid deserialize data: Error { inner: Error { inner: TomlError { message: "invalid type: map, expected unit", raw: None, keys: [], span: None } } }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test test::setting ... FAILED

using direct deserialize result in success, but using table should have success too since its same source

is there something am i missing?

@epage
Copy link
Member

epage commented Dec 2, 2024

We have multiple serializers / deserializers and a feature was likely implemented for one but not another. To address this, we'll need full reproduction steps.

@epage epage added C-enhancement Category: Raise on the bar on expectations A-serde Area: Serde integration labels Dec 2, 2024
@HadziqM
Copy link
Author

HadziqM commented Dec 2, 2024

i m sorry, Table::try_into need an explicit type on trait

so this produce success return data.try_into::<Self>()

pub trait SettingPath: Sized + DeserializeOwned + Debug {
    fn name() -> String {
        "Config".to_string()
    }
    // the location of struct in the tome example local.serial, will just deseialize inside
    // [local.serial] in toml file
    fn locate() -> impl ToString;
    fn get() -> Self {
        let file = format!("{}.toml", Self::name());
        if let Ok(x) = std::fs::read_to_string(SYSDIR.config_dir(file.clone())) {
            println!("de data succes: {:?}", toml::from_str::<Self>(&x).unwrap());
            if let Ok(mut data) = toml::from_str::<toml::Value>(&x) {
                // for pattern in Self::locate().to_string().split('.') {
                //     if let toml::Value::Table(table) = data {
                //         data = table.get(pattern).expect("invalid table name").clone();
                //     }
                // }
                return data.try_into::<Self>().expect("invalid deserialize data");
            }
        }
        panic!("{} not found", SYSDIR.config_dir(file));
    }
}

if i doesnt explicitly type it

pub trait SettingPath: Sized + DeserializeOwned + Debug {
    fn name() -> String {
        "Config".to_string()
    }
    // the location of struct in the tome example local.serial, will just deseialize inside
    // [local.serial] in toml file
    fn locate() -> impl ToString;
    fn get() -> Self {
        let file = format!("{}.toml", Self::name());
        if let Ok(x) = std::fs::read_to_string(SYSDIR.config_dir(file.clone())) {
            println!("de data succes: {:?}", toml::from_str::<Self>(&x).unwrap());
            if let Ok(mut data) = toml::from_str::<toml::Value>(&x) {
                // for pattern in Self::locate().to_string().split('.') {
                //     if let toml::Value::Table(table) = data {
                //         data = table.get(pattern).expect("invalid table name").clone();
                //     }
                // }
                data.try_into().expect("invalid deserialize data")
            }
        }
        panic!("{} not found", SYSDIR.config_dir(file));
    }
}

this will compile but error when serializing, maybe Try_into try to serialize into the trait itself? i m not really understand it

@epage
Copy link
Member

epage commented Dec 2, 2024

Can you provide a complete reproduction case, as in I should be able to drop it into a main.rs and run cargo run and see the failure.

@HadziqM
Copy link
Author

HadziqM commented Dec 2, 2024

yes

this is the full code

use serde::{de::DeserializeOwned, Deserialize};
use std::{fmt::Debug, sync::LazyLock};
use sysdir::Sysdir;

pub static SYSDIR: LazyLock<Sysdir> = LazyLock::new(|| Sysdir::custom_name("Roteksia"));

pub trait SettingPath: Sized + DeserializeOwned + Debug {
    fn name() -> String {
        "Config".to_string()
    }
    // the location of struct in the tome example local.serial, will just deseialize inside
    // [local.serial] in toml file
    fn locate() -> impl ToString;
    fn get() -> Self {
        let file = format!("{}.toml", Self::name());
        if let Ok(x) = std::fs::read_to_string(SYSDIR.config_dir(file.clone())) {
            if let Ok(mut data) = toml::from_str::<toml::Value>(&x) {
                for pattern in Self::locate().to_string().split('.') {
                    if let toml::Value::Table(table) = data {
                        data = table.get(pattern).expect("invalid table name").clone();
                    }
                }
                data.try_into().expect("invalid deserialize data");
            }
        }
        panic!("{} not found", SYSDIR.config_dir(file));
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct GithubUpdate {
    pub repo: String,
    pub owner: String,
    pub token: Option<String>,
}

impl SettingPath for GithubUpdate {
    fn locate() -> impl ToString {
        "github"
    }
}

Config.toml

[github]
repo = "ship-rework"
owner = "HadziqM"

Sysdir is just my wrapper to handle path, its equal to current dir on debug assertation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-serde Area: Serde integration C-enhancement Category: Raise on the bar on expectations
Projects
None yet
Development

No branches or pull requests

2 participants