Rust : windows下protobuf尝试

此前dbpystream库是用python开发 web api。今天在rust中试用一下protobuf。

一、 protobuf编译器下载

具体见相关文章。没有编译器,protobuf无法运行。
windows参见:
https://blog.csdn.net/wowotuo/article/details/139458846?spm=1001.2014.3001.5502。

二、proto文件的准备

proto文件中主要模拟了一个dbpystream中一个get_price函数的输入和输出的格式,输入HistoryBarRequest ,输出HistoryBarResponse。HistoryBarResponse中,有代码名称,日期,开盘价,最高价等。
在格式中,包括了string,TimeStamp,double; 其中repeated就是vec格式。

syntax = "proto3";
package dbdata;
import public "google/protobuf/timestamp.proto";
service DataService {rpc query (HistoryBarRequest) returns (HistoryBarRequest) {}
}
service Login{rpc auth (Auth) returns (Response) {}
}
message Auth{string id =1; string password=2; 
}
message HistoryBarRequest {string security  = 1;string frequency = 2;FieldParam fields     = 3;google.protobuf.Timestamp start_date = 4;//收集时间google.protobuf.Timestamp end_date = 5;//收集时间bool is_fq  =6 ; 
}
message HistoryBarResponse{repeated string securitycode = 1;repeated google.protobuf.Timestamp  datetime =2;repeated double  open = 3;repeated double  high = 4;repeated double close = 5;repeated double low =6;repeated double volume=7;repeated double amount=8;repeated sint64 is_fq = 9;
}message FieldParam{bool is_all = 1;
}message Response {bool status = 1;bytes msg   = 2;string error = 3;
}

三、toml文件、文件目录结构、build.rs
1、toml文件有

[package]
name = "clap-2"
version = "0.1.0"
edition = "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
axum = "0.7.5" # web 服务器
anyhow = "1" # 错误处理
reqwest = { version = "0.12.4", features = ["json"] } # HTTP 客户端
tokio = { version = "1", features = ["full"] } # 异步处理库
prost = "0.12.6"
# Only necessary if using Protobuf well-known types:
prost-types = "0.12.6"
serde = { version = "1", features = ["derive"] } # 序列化/反序列化数据
polars = { version = "0.39.0", features = ["json"]}
chrono = { version = "0.4", features = ["unstable-locales"] }
[build-dependencies]
prost-build = "0.12.6" # 编译 protobuf

上面polars,chrono,prost-types,prost-build,prost是关键库,其它暂时可以不看。

2、目录结构
具体如下:

PS D:\my_program\clap-2> tree /F
卷 新加卷 的文件夹 PATH 列表
卷序列号为 D855-8BFE
D:.
│  .gitignore
│  build.rs
│  Cargo.lock
│  Cargo.toml
│  dbdata.proto
│
└─src│  main.rs│└─pbdbdata.rsmod.rs

可见,在src/目录下,创建了一个pb文件夹,存放未来生成的dbdata.proto文件。

3、build.rs

fn main() {prost_build::Config::new().out_dir("src/pb")//设置proto输出目录.compile_protos(&["dbdata.proto"], &["."])//我们要处理的proto文件.unwrap();
} 

运行cargo build,即生成了dbdata.proto.

四、原始数据、main.rs

1、原始数据准备

这个原始数据的格式,即收到request后,将发送这个数据内容出去。
在这里插入图片描述文件名称是"C:\Users\Desktop\test.csv"。
这里采用了polars来读取csv文件。

2、main.rs

下面的main.rs模拟了收到resquest,发送response的过程。这个过程可以用web框架,如axum,也可以用grpc框架。这部分不是今天的重点。

use pb::dbdata::{self, HistoryBarResponse};
mod pb;
use prost_types::Timestamp;
use std::time::{Duration, SystemTime};
use polars::prelude::*;
use chrono::{NaiveDate, NaiveDateTime,NaiveTime};
fn main() ->Result<(),PolarsError>{let request = dbdata::HistoryBarRequest {security: String::from("600036.XSHG"),frequency: String::from("1minute"),fields: Some(dbdata::FieldParam {is_all:true}),start_date: Some(prost_types::Timestamp::from(SystemTime::now()-Duration::from_secs(3600*12*250))),end_date:Some(prost_types::Timestamp::from(SystemTime::now())),is_fq:true,};println!("模拟收到request:{:?}",request);println!("模拟开始进行相应的数据处理.....");let file = r"C:\Users\Desktop\test.csv";let df: DataFrame = CsvReader::from_path(file)?.has_header(true).finish().unwrap();println!("starting...");println!("df: {:?}",df);let res = HistoryBarResponse{securitycode : df.column("securitycode")?.str()?.into_no_null_iter().map(|s|String::from(s)).collect(),datetime:df.column("date")?.str()?.into_no_null_iter().map(|t| convert(t)).collect(),open:df.column("open")?.f64()?.into_no_null_iter().collect(),high:df.column("high")?.f64()?.into_no_null_iter().collect(),close:df.column("close")?.f64()?.into_no_null_iter().collect(),low:df.column("low")?.f64()?.into_no_null_iter().collect(),volume:df.column("volume")?.i64()?.into_no_null_iter().map(|v|v as f64).collect(),amount:df.column("amount")?.f64()?.into_no_null_iter().collect(),is_fq:df.column("is_fq")?.i64()?.into_no_null_iter().collect(),};//println!("{:?}", res);let encoded = prost::Message::encode_to_vec(&res);let decoded =  < pb::dbdata::HistoryBarResponse as prost::Message>::decode(&encoded[..]).unwrap();println!("模拟发送相应的数据: {:?}", &decoded.securitycode[0]);Ok(())
}
// 简单由&str生成Timestamp,这里格式是"%Y/%m/%d",只是模拟代码。
fn convert(dt_str:&str) ->Timestamp {let naive_date = NaiveDate::parse_from_str(dt_str, "%Y/%m/%d").unwrap();let nano_second = NaiveTime::from_hms_milli_opt(0, 0, 0, 0).unwrap();let dt: NaiveDateTime = naive_date.and_time(nano_second );Timestamp{seconds:dt.and_utc().timestamp(),nanos:0,}
}

运行如下:

模拟收到request:HistoryBarRequest { security: "600036.XSHG", frequency: "1minute", fields: Some(FieldParam { 
is_all: true }), start_date: Some(Timestamp { seconds: 1707035277, nanos: 595181300 }), end_date: Some(Timestamp { seconds: 1717835277, nanos: 595183100 }), is_fq: true }
模拟开始进行相应的数据处理.....
starting...
df: shape: (482, 9)
┌──────────────┬───────────┬────────┬────────┬───┬────────┬────────┬─────────────┬───────┐
│ securitycode ┆ dateopen   ┆ high   ┆ … ┆ close  ┆ volume ┆ amount      ┆ is_fq │
│ ---          ┆ ---       ┆ ---    ┆ ---    ┆   ┆ ---    ┆ ---    ┆ ---         ┆ ---   │
│ str          ┆ str       ┆ f64    ┆ f64    ┆   ┆ f64    ┆ i64    ┆ f64         ┆ i64   │
╞══════════════╪═══════════╪════════╪════════╪═══╪════════╪════════╪═════════════╪═══════╡
│ 600036.XSHG  ┆ 2021/2/3  ┆ 1210.41222.3 ┆ … ┆ 1221.5122341.4943831e7 ┆ 1     │
│ 600037.XSHG  ┆ 2021/2/4  ┆ 1210.51222.4 ┆ … ┆ 1221.6122351.4946276e7 ┆ 1     │
│ 600038.XSHG  ┆ 2021/2/5  ┆ 1210.61222.5 ┆ … ┆ 1221.7122361.4949e7    ┆ 1     │
│ 600039.XSHG  ┆ 2021/2/6  ┆ 1210.71222.6 ┆ … ┆ 1221.8122371.4951e7    ┆ 1     │
│ 600040.XSHG  ┆ 2021/2/7  ┆ 1210.81222.7 ┆ … ┆ 1221.9122381.4954e7    ┆ 1     │
│ …            ┆ …         ┆ …      ┆ …      ┆ … ┆ …      ┆ …      ┆ …           ┆ …     │
│ 600513.XSHG  ┆ 2022/5/26 ┆ 1258.11270.0 ┆ … ┆ 1269.2127111.6133e7    ┆ 1     │
│ 600514.XSHG  ┆ 2022/5/27 ┆ 1258.21270.1 ┆ … ┆ 1269.3127121.6135e7    ┆ 1     │
│ 600515.XSHG  ┆ 2022/5/28 ┆ 1258.31270.2 ┆ … ┆ 1269.4127131.6138e7    ┆ 1     │
│ 600516.XSHG  ┆ 2022/5/29 ┆ 1258.41270.3 ┆ … ┆ 1269.5127141.6140423e7 ┆ 1     │
│ 600517.XSHG  ┆ 2022/5/30 ┆ 1258.51270.4 ┆ … ┆ 1269.6127151.6142964e7 ┆ 1     │
└──────────────┴───────────┴────────┴────────┴───┴────────┴────────┴─────────────┴───────┘
模拟发送相应的数据: "600036.XSHG"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/24542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐系统三十六式学习笔记:原理篇.内容推荐05|从文本到用户画像有多远?

目录 从文本开始构建用户画像一、结构化文本1、TF-IDF2、TextRank3、内容分类&#xff1a;4、实体识别5、聚类6、词嵌入 二、标签选择1、卡方检验2、信息增益 总结 对于一个早期的推荐系统来说&#xff0c;基于内容推荐离不开用户构建一个初级的画像&#xff0c;这种初级的画像…

【数据结构】栈的应用

目录 0 引言 1 栈在括号匹配中的应用 2 栈在表达式求值中的应用 2.1 算数表达式 2.2 中缀表达式转后缀表达式 2.3 后缀表达式求值 3 栈在递归中的应用 3.1 栈在函数调用中的作用 3.2 栈在函数调用中的工作原理 4 总结 0 引言 栈&#xff08;Stack&#xff09;是一…

MySQL A表的字段值更新为B表的字段值

MySQL A表的字段值更新为B表的字段值 准备数据表 create table person (id int unsigned auto_increment comment 主键 primary key,uuid varchar(32) not null comment 系统唯一标识符32个长度的字符串,mobile varchar(11) null comment 中国国内手机号,nickn…

使用 Ollama 和 Open WebUI 自托管 LLM 聊天机器人(无需 GPU)

✨点击这里✨&#xff1a;&#x1f680;原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 使用 Ollama 和 Open WebUI 自托管 LLM 聊天机器人&#xff08;无需 GPU&#xff09; &#x1f31…

二叉查找树详解

目录 二叉查找树的定义 二叉查找树的基本操作 查找 插入 建立 删除 二叉树查找树的性质 二叉查找树的定义 二叉查找树是一种特殊的二叉树&#xff0c;又称为排序二叉树、二叉搜索树、二叉排序树。 二叉树的递归定义如下&#xff1a; &#xff08;1&#xff09;要么二…

10. MySQL 用户

文章目录 【 1. 权限表 】1.1 user 权限表1.1.1 用户列1.1.2 权限列1.1.3 安全列1.1.4 资源控制列 1.2 db 表用户列权限列 1.3 tables_priv 表1.4 columns_priv 表1.5 procs_priv表 【 2. 用户管理 】2.1 创建用户 CREATE USER2.2 用户的登陆、退出登陆 MySQL退出 MySQL 2.3 重…

Java常见错误-内部类-简要分析

Java常见错误-内部类-简要分析 概念分类成员内部类&#xff08;非静态内部类&#xff09;静态内部类成员内部类和静态内部类区别 局部内部类匿名内部类 注意事项总结 概念 ​ 内部类&#xff0c;顾名思义&#xff0c;就是在一个类的内部定义的类。这种设计允许将一个类的实现细…

深度学习-10-测试

深度学习-10-测试 本文是《深度学习入门2-自製框架》 的学习笔记&#xff0c;记录自己学习心得&#xff0c;以及对重点知识的理解。如果内容对你有帮助&#xff0c;请支持正版&#xff0c;去购买正版书籍&#xff0c;支持正版书籍不仅是尊重作者的辛勤劳动&#xff0c;也是鼓励…

Web前端ES6-ES13笔记合集(下)

#### 五.ES10新特性 ##### 1. Object.fromEntries > Object.fromEntries()方法允许你轻松地将键值对列表转换为对象 js const arr [["name", "kerwin"], ["age", 100]]; console.log(Object.fromEntries(arr))//{name: kerwin, age: 100} …

pytorch 笔记:pytorch 优化内容(更新中)

1 Tensor创建类 1.1 直接创建Tensor&#xff0c;而不是从Python或Numpy中转换 不要使用原生Python或NumPy创建数据&#xff0c;然后将其转换为torch.Tensor直接用torch.Tensor创建或者直接&#xff1a;torch.empty(), torch.zeros(), torch.full(), torch.ones(), torch.…

树莓派【Raspberry Pi-64位】3b+,Pi4J 2.0入门

一.前言: 前面的文章讲解了树莓派在centos7 arm64版本下的使用,用一款智能小车为例子,做了代码实践。 由于centos7不再维护,且Pi4J 1.x版本也因为WiringPi 的局限,Pi4J从1.x升级为2.x.所以本专栏的技术栈也将进行调整,A.从centos7系统回到Raspberry Pi-64位系统。B.Pi4…

4.通用编程概念

目录 一、变量与常量1.1 变量1.2 常量 二、遮蔽三、数据类型3.1 标量类型1. 整型2. 浮点型3. 布尔类型4.字符类型 3.2 复合类型1. 元组2. 数组 四、函数五、语句和表达式六、函数的返回值 一、变量与常量 1.1 变量 在Rust中默认的变量是不可变的&#xff0c;如果修改其值会导致…

《青少年编程与数学》课程方案:4、课程策略

《青少年编程与数学》课程方案&#xff1a;4、课程策略 一、工程师思维二、使命感驱动三、价值观引领四、学习现代化五、工作生活化六、与时代共进 《青少年编程与数学》课程策略强调采用工程师思维&#xff0c;避免重复造轮子&#xff0c;培养使命感&#xff0c;通过探索兴趣、…

编程语言有哪些?这些希望你都知道

编程语言有哪些 编程语言有很多种&#xff0c;包括但不限于以下几种&#xff1a; Java&#xff1a;当今最普遍使用的开发语言之一&#xff0c;简单易学&#xff0c;且跨平台性非常强&#xff0c;对网络开发的支持令人称赞。Python&#xff1a;语法清楚&#xff0c;干净&#…

【Vue】如何提供访问vuex的数据

文章目录 一、提供数据二、访问Vuex中的数据通过$store访问的语法1&#xff09;模板中使用2&#xff09;组件逻辑中使用3&#xff09;js文件中使用 三、通过辅助函数 - mapState获取 state中的数据 一、提供数据 State提供唯一的公共数据源&#xff0c;所有共享的数据都要统一…

[office] 快速删除excel中的空行和列的方法 #其他#学习方法#经验分享

快速删除excel中的空行和列的方法 用户在网上下载好的Excel表格打开之后发现有很多空白行&#xff0c;怎么样将这些空白行或单元格一次性删除掉呢?下面教大家在Excel中用定位一次性可以把空白行删除 用户在网上下载好的Excel表格打开之后发现有很多空白行&#xff0c;怎么样将…

Vue3 使用audio播放语音+监听播放语音完成事件

需求&#xff1a;输入一段文字&#xff0c;点击语音框&#xff0c;将本地语音&#xff08;提前准备好的&#xff09; 播放出来 播放中效果 代码 <div class"listConAI" click"handleOpenSpeech" ><imgsrc"../../../../assets/images/blueo…

web前端 孙俏:深度探索与实战之路

web前端 孙俏&#xff1a;深度探索与实战之路 在这个数字化、信息化的时代&#xff0c;web前端技术以其独特的魅力&#xff0c;吸引着越来越多的开发者投身其中。今天&#xff0c;我们将跟随孙俏的脚步&#xff0c;一同探索web前端的深度与广度&#xff0c;揭开其神秘的面纱。…

中文文案写作有哪些合适的AIGC工具?

这是计育韬老师第 8 次开展面向全国高校的新媒体技术公益巡讲活动了。而在每场讲座尾声&#xff0c;互动答疑环节往往反映了高校师生当前最普遍的运营困境&#xff0c;特此计老师在现场即兴答疑之外&#xff0c;会尽量选择有较高价值的提问进行文字答疑梳理。 *本轮巡讲主题除了…

【Vue】开启严格模式及Vuex的单项数据流

文章目录 一、引出问题二、开启严格模式 一、引出问题 目标 明确 vuex 同样遵循单向数据流&#xff0c;组件中不能直接修改仓库的数据 这样数据的流向才会更加清晰&#xff0c;将来对数据的修改&#xff0c;都在仓库内部实现的&#xff0c;更易于维护 直接在组件中修改Vuex中…