2 个不稳定版本
0.2.0 | 2024年2月18日 |
---|---|
0.1.0 | 2023年11月1日 |
#1500 in 编码
84KB
2K SLoC
nml
使用 Rust 和 serde 框架序列化和反序列化 Fortran namelist 输入。
用法
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Particle {
index: i32,
position: [f32; 3],
velocity: [f32; 3]
}
fn main() -> Result<(), nml::NamelistError>{
let s = r#"
&particle
index = 0,
position = 0.0, 0.0, 0.0,
velocity = 1.0, 0.0, 0.0,
/"#;
let particle: Particle = nml::group_from_str(s)?.1;
println!("{:#?}", particle);
Ok(())
}
lib.rs
:
Fortran Namelist 输入的 serde 库。
Namelist 是 Fortran 90 的一种特性,用于以键值赋值格式输入和输出变量组。
&particle
timestep = 0,
mass = 1.0
position = 1.0, 1.0, 1.0,
velocity = -1.0, 0.0, 0.0
/
此 namelist 组分配一个整型变量 timestep
,一个浮点型/实型变量 masss
和两个实型数组 position
和 velocity
。namelist 输入格式支持的进一步数据类型包括布尔值/逻辑值(用 .TRUE.
或 .FALSE.
赋值)和字符串(由单引号 'hello'
或双引号 "hello"
表示)
用法
要将 Rust 结构体(或映射)序列化和反序列化为 Namelist 组,可以使用 group_from_str
和 group_to_string
方法
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Particle {
timestep: i32,
mass: f32,
position: [f32; 3],
velocity: [f32; 3]
}
fn main() -> Result<(), nml::NamelistError> {
let p = Particle {
timestep: 0,
mass: 1.0,
position: [0.0, 0.0, 0.0],
velocity: [-1.0, 0.0, 0.0]
};
let serialized = nml::group_to_string(p)?;
let deserialized = nml::group_from_str(&serialized)?;
assert_eq!(p, deserialized);
Ok(())
}
要从单个输入中反序列化多个 Namelist 组(具有相同或不同的组名)到 Rust 结构体或映射,可以使用 NamelistInput
类型
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Simulation {
start_time: i32,
timesteps: i32
}
#[derive(Deserialize, Debug)]
struct Particle {
index: i32,
position: [f32; 3],
velocity: [f32; 3]
}
fn main() -> Result<(), nml::NamelistError>{
let s = r#"
&simulation
start_time: 0,
timesteps: 10,
/
&particle
index = 0,
position = 0.0, 0.0, 0.0,
velocity = 1.0, 0.0, 0.0,
/
&particle
index = 1,
position = 1.0, 0.0, 0.0,
velocity = -1.0, 0.0, 0.0,
/"#;
let input = NamelistInput::try_from_str(s)?;
let mut simulation = None;
let mut particles = Vec::new();
for group in &input {
if group.name() == "particle" {
let particle = Particle::deserialize(group)?;
particles.push(particle);
} else if group.name() == "simulation" {
simulation = Some(Simulation::deserialize(group)?);
}
}
Ok(())
}
如你所见,NamelistInput
类型可以解析多个 namelist 组,并且可以被转换为迭代器,每次产生一个 GroupRefDeserializer
实例,对应输入中的每个 namelist 组。此类型可用于将 namelist 组反序列化为 Rust 结构体或映射。
支持的 Namelist 语法
支持
- 所有基本数据类型,整数,逻辑,字符串,实数
- 数组:使用下标分配序列和单个元素
- 派生类型
不支持:
- 涉及切片操作符
:
的任何内容,例如:var(1:3) = 1, 2, 3,
- 将序列赋值给下标变量,即
var(1) = 1, 2, 3
依赖关系
~110–350KB