Rust SPDX许可证解析库spdx-rs的使用,支持SPDX许可证表达式解析与验证
Rust SPDX许可证解析库spdx-rs的使用,支持SPDX许可证表达式解析与验证
SPDX Documents in Rust
spdx-rs
是一个用于解析SPDX文档到Rust结构体的库,支持多种数据格式。
数据格式
该库主要设计用于处理JSON格式的SPDX文档。这是通过Serde实现的,因此任何Serde支持的数据格式都可以工作,只要命名与JSON SPDX文档中使用的命名一致。
除了使用Serde进行序列化和反序列化外,还支持使用自定义解析器反序列化tag-value格式的文档。
使用
以下是使用spdx-rs库解析和验证SPDX许可证表达式的完整示例:
use spdx_rs::models::LicenseExpression;
use spdx_rs::validation::validate_license_expression;
fn main() {
// 示例SPDX许可证表达式
let expr_str = "MIT OR (Apache-2.0 AND BSD-3-Clause)";
// 解析许可证表达式
let expr = LicenseExpression::parse(expr_str).unwrap();
println!("Parsed expression: {:?}", expr);
// 验证许可证表达式
match validate_license_expression(&expr) {
Ok(_) => println!("License expression is valid"),
Err(e) => println!("Validation error: {}", e),
}
// 另一个更复杂的例子
let complex_expr = "GPL-2.0-only WITH Classpath-exception-2.0 AND MIT";
match LicenseExpression::parse(complex_expr) {
Ok(expr) => {
println!("Successfully parsed complex expression");
if let Err(e) = validate_license_expression(&expr) {
println!("Warning: {}", e);
}
}
Err(e) => println!("Parse error: {}", e),
}
}
项目信息
- 版本: 0.5.5
- 许可证: MIT
- 大小: 29.1 KiB
- 依赖: 2018 edition
- 最后更新: 约2年前
- 分类: 数据结构
完整示例代码
use spdx_rs::models::LicenseExpression;
use spdx_rs::validation::validate_license_expression;
fn main() {
// 示例1: 简单许可证表达式解析与验证
let simple_expr = "MIT OR Apache-2.0";
match LicenseExpression::parse(simple_expr) {
Ok(expr) => {
println!("成功解析简单表达式: {:?}", expr);
if let Err(e) = validate_license_expression(&expr) {
println!("验证错误: {}", e);
} else {
println!("表达式验证通过");
}
}
Err(e) => println!("解析错误: {}", e),
}
// 示例2: 带括号的复杂表达式
let nested_expr = "(MIT AND BSD-2-Clause) OR GPL-3.0-only";
if let Ok(expr) = LicenseExpression::parse(nested_expr) {
println!("解析带括号的复杂表达式成功");
match validate_license_expression(&expr) {
Ok(_) => println!("复杂表达式验证通过"),
Err(e) => println!("复杂表达式验证失败: {}", e),
}
}
// 示例3: 带异常条款的表达式
let with_exception = "LGPL-2.1-only WITH Classpath-exception-2.0";
if let Ok(expr) = LicenseExpression::parse(with_exception) {
println!("成功解析带异常条款的表达式");
if validate_license_expression(&expr).is_ok() {
println!("带异常条款的表达式验证通过");
}
}
}
安装
在项目目录中运行以下Cargo命令:
cargo add spdx-rs
或者在Cargo.toml中添加:
spdx-rs = "0.5.5"
所有者
- Mikko Murto (mmurto)
1 回复
Rust SPDX许可证解析库spdx-rs使用指南
概述
spdx-rs是一个用于解析和验证SPDX许可证标识符和表达式的Rust库。它支持SPDX许可证列表中的所有标准许可证标识符,并能解析复杂的SPDX许可证表达式。
主要功能
- 解析和验证SPDX许可证标识符
- 解析和验证SPDX许可证表达式
- 支持SPDX 3.0规范
- 提供详细的错误信息
安装
在Cargo.toml中添加依赖:
[dependencies]
spdx = "0.8.0"
基本使用方法
验证单个许可证标识符
use spdx::LicenseId;
fn main() {
match LicenseId::parse("MIT") {
Ok(license) => println!("有效的SPDX许可证: {:?}", license),
Err(e) => println!("无效的许可证标识符: {}", e),
}
}
解析许可证表达式
use spdx::Expression;
fn main() {
let expr = "MIT OR Apache-2.0";
match Expression::parse(expr) {
Ok(parsed) => println!("解析成功: {}", parsed),
Err(e) => println!("解析失败: {}", e),
}
}
检查表达式有效性
use spdx::Expression;
fn main() {
let expr = "(MIT AND Apache-2.0) OR GPL-3.0-only WITH Classpath-exception-2.0";
match Expression::parse(expr) {
Ok(parsed) => {
println!("表达式有效: {}", parsed);
println!("包含的许可证:");
for req in parsed.requirements() {
println!("- {}", req.license.id());
}
}
Err(e) => println!("无效表达式: {}", e),
}
}
高级用法
自定义许可证解析
use spdx::{Expression, ParseOptions};
fn main() {
let options = ParseOptions {
allow_lower_case: true, // 允许小写许可证标识符
..Default::default()
};
let expr = "mit or apache-2.0";
match Expression::parse_with_options(expr, &options) {
Ok(parsed) => println!("解析成功: {}", parsed),
Err(e) => println!("解析失败: {}", e),
}
}
检查许可证是否满足特定条件
use spdx::{LicenseId, LicenseExceptionId};
fn main() {
let license = LicenseId::parse("GPL-3.0-only").unwrap();
let exception = LicenseExceptionId::parse("Classpath-exception-2.0").unwrap();
println!("GPL-3.0-only是自由软件许可证: {}", license.is_fsf_libre());
println!("Classpath-exception-2.0是FSF批准的例外: {}", exception.is_fsf_exception());
}
实际应用示例
在项目中使用许可证检查
use spdx::Expression;
struct Project {
name: String,
license: String,
}
fn check_project_license(project: &Project) {
match Expression::parse(&project.license) {
Ok(expr) => {
println!("项目 {} 使用有效的SPDX许可证表达式", project.name);
if expr.evaluate(|req| {
req.license.id().is_fsf_libre()
}) {
println!(" -> 符合自由软件定义");
}
}
Err(e) => println!("项目 {} 的许可证无效: {}", project.name, e),
}
}
fn main() {
let projects = vec![
Project {
name: "MyApp".to_string(),
license: "MIT OR Apache-2.0".to_string(),
},
Project {
name: "OtherLib".to_string(),
license: "Invalid-License".to_string(),
},
];
for project in projects {
check_project_license(&project);
}
}
错误处理
spdx-rs提供了详细的错误信息,帮助调试许可证表达式问题:
use spdx::Expression;
fn main() {
let expr = "MIT AND (Apache-2.0 OR )";
if let Err(e) = Expression::parse(expr) {
println!("错误位置: {}", e.span);
println!("错误原因: {}", e.reason);
if let Some(help) = e.help {
println!("建议: {}", help);
}
}
}
完整示例
下面是一个完整的示例,展示了如何使用spdx-rs库进行许可证验证和表达式解析:
use spdx::{LicenseId, LicenseExceptionId, Expression, ParseOptions};
fn main() {
// 示例1: 验证单个许可证标识符
println!("--- 验证单个许可证标识符 ---");
let licenses_to_check = ["MIT", "Apache-2.0", "Invalid-License"];
for license_str in licenses_to_check {
match LicenseId::parse(license_str) {
Ok(license) => println!("'{}' 是有效的SPDX许可证", license_str),
Err(e) => println!("'{}' 无效: {}", license_str, e),
}
}
// 示例2: 解析复杂许可证表达式
println!("\n--- 解析复杂许可证表达式 ---");
let complex_expr = "(MIT AND Apache-2.0) OR (GPL-3.0-only WITH Classpath-exception-2.0)";
match Expression::parse(complex_expr) {
Ok(expr) => {
println!("表达式解析成功:");
println!("规范化形式: {}", expr);
println!("包含的许可证:");
for req in expr.requirements() {
println!("- {}", req.license.id());
if let Some(exception) = req.exception {
println!(" 带有例外: {}", exception);
}
}
}
Err(e) => println!("解析失败: {}", e),
}
// 示例3: 自定义解析选项
println!("\n--- 自定义解析选项 ---");
let options = ParseOptions {
allow_lower_case: true,
..Default::default()
};
let lower_case_expr = "mit or apache-2.0";
match Expression::parse_with_options(lower_case_expr, &options) {
Ok(expr) => println!("成功解析小写表达式: {}", expr),
Err(e) => println!("解析失败: {}", e),
}
// 示例4: 检查许可证属性
println!("\n--- 检查许可证属性 ---");
let gpl_license = LicenseId::parse("GPL-3.0-only").unwrap();
let exception = LicenseExceptionId::parse("Classpath-exception-2.0").unwrap();
println!("{} 是OSI批准的: {}", gpl_license, gpl_license.is_osi_approved());
println!("{} 是自由软件许可证: {}", gpl_license, gpl_license.is_fsf_libre());
println!("{} 是FSF批准的例外: {}", exception, exception.is_fsf_exception());
// 示例5: 错误处理
println!("\n--- 错误处理示例 ---");
let invalid_expr = "MIT AND (Apache-2.0 OR )";
if let Err(e) = Expression::parse(invalid_expr) {
println!("发现错误:");
println!("位置: {}", e.span);
println!("原因: {}", e.reason);
if let Some(help) = e.help {
println!("建议: {}", help);
}
}
}
总结
spdx-rs库为Rust项目提供了强大的SPDX许可证解析和验证能力,非常适合需要处理软件许可证的工具和应用程序。通过简单的API,开发者可以轻松集成SPDX标准到自己的项目中。