使用serde_json :: from_str反序列化为带有&'static字符串的结构会导致生命周期错误

贾·基斯特德

我正在尝试测试设置用于Dart,JS和Python UI框架的JSON桥。这对于那些很好用,但是当我尝试使用tui-rs在Rust程序中进行相同的UI /逻辑拆分时,在尝试反序列化UI线程上的逻辑线程结果时,我收到了生命周期错误。

我了解使用JSON在两个用Rust编写的层之间进行通信不是理想的处理方式,但是鉴于我的目标,我希望它是可以理解的。

我尝试了克隆,该克隆可用于将事物序列化并从UI发送到逻辑,但这不适用于从逻辑到UI的反序列化

use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
use serde::{Deserialize, Serialize};

#[macro_export]
macro_rules! BridgeResult {
    ($result:expr, $data:expr) => {
        BridgeResult {
            result: $result,
            data: vec![$data.to_string()],
        }
    };
}

#[derive(Serialize, Deserialize)]
struct BridgeResult {
    result: &'static str,
    data: Vec<String>,
}

#[derive(Serialize, Deserialize)]
struct App {
    state: i64,
}

impl Default for App {
    fn default() -> App {
        App { state: 0 }
    }
}

fn main() {
    let (to_logic, from_ui) = mpsc::channel();
    let (to_ui, from_logic) = mpsc::channel();

    ui(to_logic, from_logic);
    logic(to_ui, from_ui);
}

fn ui(tx: Sender<(String, String)>, rx: Receiver<(String)>) {
    let app = App::default();

    let app_string = serde_json::to_string(&app)
        .expect("failed to encode app struct for sending to logic heard");

    tx.send(("binary_switch".to_string(), app_string))
        .expect("failed to send binary_switch call and data to logic thread");
    let output_string = rx
        .recv()
        .expect("failed to get a result from logic's initialize");
    let output: BridgeResult = serde_json::from_str(&output_string)
        .expect("failed to decode result from logic's binary_switch");

    if output.result != "Ok()" {
        panic!("init failed due to: \n {:?}", output.data);
    } else {
        println!("{:?}", output.data);
    }
}

fn logic(tx: Sender<(String)>, rx: Receiver<(String, String)>) {
    loop {
        let (function, arguments) = rx
            .recv()
            .expect("failed to receive function and arguments from ui thread");
        let result = match function.as_str() {
            "binary_switch" => binary_switch(&arguments),
            _ => {
                BridgeResult! {"Err()", format!("cannot find rust function branch matching {}", function)}
            }
        };

        let output = match serde_json::to_string(&result) {
            Ok(output) => output,
            Err(_) => "{'result' : 'Err()', 'data': 'failed exit encoding!!!'}".to_string(),
        };
        tx.send(output)
            .expect("failed to send the output back to the ui thread");
    }
}

fn binary_switch(data: &String) -> BridgeResult {
    #[derive(Deserialize)]
    struct Arguments {
        state: i64,
    }

    let mut arguments: Arguments = match serde_json::from_str(&data) {
        Ok(data) => data,
        Err(err) => return BridgeResult! {"Err()", format!("failed to parse arguments\n, {}", err)},
    };

    if arguments.state == 0 {
        arguments.state += 1;
    } else {
        arguments.state -= 1;
    }

    BridgeResult! {"Ok()", arguments.state}
}

我希望这可以反序列化BridgeResult类型并使用应在其中包含字符串1的数据字段。实际上,我得到:

error[E0597]: `output_string` does not live long enough
  --> src/main.rs:55:53
   |
55 |     let output: BridgeResult = serde_json::from_str(&output_string)
   |                                ---------------------^^^^^^^^^^^^^^-
   |                                |                    |
   |                                |                    borrowed value does not live long enough
   |                                argument requires that `output_string` is borrowed for `'static`
...
63 | }
   | - `output_string` dropped here while still borrowed
ggriffiniii
struct BridgeResult {
    result: &'static str,
    data: Vec<String>,
}

BridgeResult被定义为包含result一个静态字符串。这与将要从输入字符串反序列化的内容不兼容。您要么需要结果是拥有的,要么需要String从输入中借来的东西。

尝试

struct BridgeResult<'a> {
    result: &'a str,
    data: Vec<String>,
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将具有特殊字符的JSON反序列化为字符串

如何正确地将带有String()方法的嵌入式结构序列化为JSON字符串?

返回Vec <&str>时字符串的生命周期

Newtonsoft Json将具有布尔属性的动态列表反序列化为字符串

当使用将在函数末尾删除的String调用时,如何返回serde_json :: from_str的结果?

如何使用Serde从原始结构的JSON反序列化结构的子字段?

使用JSON.NET将JSON数组反序列化为字符串数组

无法将带有JSON内容的字符串反序列化为C#对象

为什么在尝试使用serde_json解析数据时总是出现“尾随字符”错误?

如何派生serde :::反序列化具有生命周期成员的结构

使用serde_json使用非字符串键序列化地图

反序列化为带有json字符串缺少的enum属性的模型时,强制System.Text.Json失败

如何使用serde将JSON数组反序列化为结构?

使用serde_json将内部枚举值从&str反序列化为u64

ServiceStack.Text json序列化程序将带有括号的原始字符串反序列化为jsv

&str字符串和生命周期

将JSON字符串反序列化为Class

Json.net 将所有空字符串反序列化为 null

使用 serde,是否可以反序列化为实现类型的结构?

无法将 Json 文件反序列化为带有字符串“key”的 KeyValuePair 列表

Serde_json 使用泛型序列化 to_string

使用字符串时 Rust 的生命周期

强类型对象的通用 serde_json 反序列化函数

带有反序列化和通用函数生命周期的 serde_json

有没有办法像反序列化那样派生结构以从 serde_json::Value 获得自动转换?

在 Rust 中,将带有可选参数的平面 JSON 反序列化为嵌套的结构和枚举

尝试使用 serde_json 解析字符串时出现“尾随字符”错误

将具有多个元素的 JSON 字段从字符串反序列化为 Vec<u8>s 的 Vec

在 rust 中从 API 反序列化 serde_json