Бесполезная ошибка при десериализации toml из файла - PullRequest
1 голос
/ 09 июля 2020

задействованных ящиков: toml = "0.5.6" serde = {version = "1.0", features = ["derive"]}

Я пытаюсь десериализовать данные toml, созданные путем сохранения вывода toml :: to_string () на диск. Код компилируется, но во время выполнения возникает паника из-за бесполезной ошибки.

Я вызываю init_cfg () с кажущимся допустимым путем к тестовому файлу для генерации конфигурации моего приложения.

Структура файла:

C:.
├───.vscode
├───res
│   ├───cfg
         #cfg.toml here
│   ├───fonts
│   │   └───FiraCode-5.2
│   ├───layout
│   ├───splits
│   └───sys
├───src

cfg.toml:

title = "title"
width = 400
height = 600

код

#[derive(Debug, Serialize, Deserialize)]
pub struct Cfg {
    pub title: String,
    pub width: u32,
    pub height: u32,
}
pub fn init_cfg(cfg_path: &Path) -> Box<Self> {
        let mut config = Cfg::default();
        // Check to see if config exists
        if cfg_path.exists() {
            // Load config
            config = *Self::read(cfg_path);

            // Return heap allocated Cfg instance
            return Box::new(config);
        } else {
            // Write config to disk
            match Self::write(cfg_path, &config) {
                // Return config
                Ok(_count) => Box::new(config),
                Err(e) => {
                    println!("Failed to write default config.");
                    panic!(e)
                },
            }
        }

    }
pub fn read(path: &Path) -> Box<Self> {
        // Open file
        if path.exists() {
            let mut file = match File::open(path) {
                Ok(file) => file,
                Err(err) => {
                    println!("Failed to open config file for reading.");
                    panic!(err)
                }
            };

            // Read file into buffer
            let mut buffer = Vec::new();
            match file.read(&mut *buffer) {
                Ok(_size) => {},
                Err(err) => {
                    print!("Failed to read cfg file into buffer");
                    panic!(err)
                }
            };

            // Deserialize Cfg
            Box::new(match toml::from_slice(&buffer) {
                Ok(config) => config,
                Err(err) =>
                    println!("Failed to deserialize user config.");
                    // Line 81
                    panic!(err)
                }
            })
        } else {
            panic!("No cofig file at given path.")
        }
    }

cout:

Running `target\debug\picosplit.exe`
Failed to deserialize user config.
 thread 'main' panicked at 'Box<Any>', src\cfg.rs:81:21
 stack backtrace:
    0: backtrace::backtrace::dbghelp::trace
              at C:\Users\VssAdministrator\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.46\src\backtrace/dbghelp.> rs:88      
    1: backtrace::backtrace::trace_unsynchronized
              at C:\Users\VssAdministrator\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.46\src\backtrace/mod.rs:66
    2: std::sys_common::backtrace::_print_fmt
              at src\libstd\sys_common/backtrace.rs:78
    3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
              at src\libstd\sys_common/backtrace.rs:59
    4: core::fmt::write
              at src\libcore\fmt/mod.rs:1076
    5: std::io::Write::write_fmt
              at src\libstd\io/mod.rs:1537
    6: std::sys_common::backtrace::_print
              at src\libstd\sys_common/backtrace.rs:62
    7: std::sys_common::backtrace::print
              at src\libstd\sys_common/backtrace.rs:49
    8: std::panicking::default_hook::{{closure}}
              at src\libstd/panicking.rs:198
    9: std::panicking::default_hook
              at src\libstd/panicking.rs:217
   10: std::panicking::rust_panic_with_hook
              at src\libstd/panicking.rs:526
   11: std::panicking::begin_panic
              at C:\Users\lmpri\scoop\persist\rustup\.rustup\toolchains\nightly-x86_64-pc-windows-gnu\lib/rustlib/src/> rust\src\libstd/panicking.rs:456
   12: picosplit::cfg::Cfg::read
              at src/cfg.rs:81
   13: picosplit::cfg::Cfg::init_cfg
              at src/cfg.rs:36
   14: picosplit::main
              at src/main.rs:18
   15: std::rt::lang_start::{{closure}}
              at C:\Users\lmpri\scoop\persist\rustup\.rustup\toolchains\nightly-x86_64-pc-windows-gnu\lib/rustlib/src/> rust\src\libstd/rt.rs:67
   16: std::rt::lang_start_internal::{{closure}}
              at src\libstd/rt.rs:52
   17: std::panicking::try::do_call
              at src\libstd/panicking.rs:348
   18: std::panicking::try
              at src\libstd/panicking.rs:325
   19: std::panic::catch_unwind
              at src\libstd/panic.rs:394
   20: std::rt::lang_start_internal
              at src\libstd/rt.rs:51
   21: std::rt::lang_start
              at C:\Users\lmpri\scoop\persist\rustup\.rustup\toolchains\nightly-x86_64-pc-windows-gnu\lib/rustlib/src/rust\src\libstd/rt.rs:67
   22: main
   23: __tmainCRTStartup
              at D:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:339
   24: mainCRTStartup
              at D:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:223
   25: units_search
   26: units_search

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Данные не считываются в буфер правильно. буфер является пустым вектором при достижении строки 81, вызывая сбой десериализации.

изменено

match file.read(&mut *buffer) {...};

на

file.read_to_end(&mut buffer).expect("Failed to read cfg file into buffer");

Извините, я новичок в язык и СО.

0 голосов
/ 09 июля 2020

Код компилируется, но во время выполнения возникает паника из-за бесполезной ошибки.

Это потому, что вы вставляете туда произвольный тип ошибки, что приводит к появлению Box, как описано в документации:

pani c каждого потока может быть получен как тип Box, так и форма pani c с одним аргументом! макрос будет значением, которое будет передано.

Вместо этого вы могли бы использовать:

Больше ничем не могу помочь, поскольку вы не предоставляете работоспособного варианта воспроизведения.

И как только вы получите полезное сообщение об ошибке, вы можете захотеть взглянуть на собственный трекер ошибок проекта, как в некоторых крайних случаях существуют известные проблемы с круговым отключением, например https://github.com/alexcrichton/toml-rs/issues/388

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...