1 个不稳定版本
0.1.0 | 2023 年 10 月 6 日 |
---|
#37 in #symlink
24 每月下载量
用于 3 个 Crates (2 直接)
63KB
1.5K SLoC
此 crate 提供了从文本形式构建 [SchemaNode] 树的方法(见 [parse_schema])。
文本形式的语言使用重要空白(四个空格)进行缩进,通过存在 /
区分文件和目录,并通过存在 ->
(后跟其目标路径表达式)来判断是否为符号链接。即目录树中的每个缩进节点具有以下形式之一
语法 | 描述 |
---|---|
str | 一个文件 |
str/ |
一个目录 |
str -> expr |
指向文件的符号链接 |
str/ -> expr |
指向目录的符号链接 |
使用以下标签设置给定节点的属性
标签 | 类型 | 描述 |
---|---|---|
:owner expr |
所有 | 设置此文件/目录/符号链接目标的拥有者 |
:group expr |
所有 | 设置此文件、目录或符号链接目标的组 |
:mode 八进制 |
所有 | 设置此文件/目录/符号链接目标的权限 |
:source expr |
文件 | 将 expr 给定的路径内容复制到此文件中 |
:let ident = expr |
目录 | 在此级别设置变量,供更深层使用 |
:def ident |
目录 | 定义一个可由 :use 重复使用的子模式 |
:use ident |
目录 | 重复使用由 :def 定义的子模式 |
简单模式
模式的第一层描述了一个目录,其[属性][Attributes]可以由:owner
、:group
和:mode
标签设置。
use diskplan_schema::*;
let schema_root = parse_schema("
:owner person
:group user
:mode 777
")?;
assert!(matches!(schema_root.schema, SchemaType::Directory(_)));
assert_eq!(schema_root.attributes.owner.unwrap(), "person");
assert_eq!(schema_root.attributes.group.unwrap(), "user");
assert_eq!(schema_root.attributes.mode.unwrap(), 0o777);
一个[DirectorySchema]可以包含子目录和文件。
#
// ...
"
subdirectory/
:owner admin
:mode 700
file_name
:source content/example_file
"
// ...
assert_eq!(
parse_schema(text)?
.schema
.as_directory()
.expect("Not a directory")
.entries()
.len(),
2
);
它还可以包含指向目录和文件的符号链接,其自身的模式将应用于目标。
#
// ...
"
example_link/ -> /another/disk/example_target/
:owner admin
:mode 700
file_to_create_at_target_end
:source content/example_file
"
// ...
#
let (binding, node) = directory.entries().first().unwrap();
assert!(matches!(
binding,
Binding::Static(ref name) if name == &String::from("example_link")
));
assert_eq!(
node.symlink.as_ref().unwrap().to_string(),
String::from("/another/disk/example_target/")
);
assert!(matches!(node.schema, SchemaType::Directory(_)));
#
#
变量替换
变量可以用来驱动构建,例如
"
:let asset_type = character
:let asset_name = Monkey
assets/
$asset_type/
$asset/
reference/
"
变量也会拾取磁盘上已有的名称(即使一个:let
提供了不同的值)。例如,如果我们已经在磁盘上有了assets/prop/Banana
,那么$asset_type
会与“prop”匹配(以及“character”),而$asset
将获取“Banana”的值(以及“Monkey”),生成
assets
├── character
│ └── Monkey
│ └── reference
└── prop
└── Banana
└── reference
模式匹配
模式中的任何节点都可以有一个:match
标签,它通过正则表达式控制变量可以取的可能值。
重要: 没有任何两个变量可以匹配相同的值。如果它们匹配,则在执行过程中将发生错误,因此请务必确保模式之间没有重叠。使用:avoid
可以帮助限制模式匹配并确保适当的分区。
静态名称(不带变量)始终具有优先级,并且不需要与变量模式(反之亦然)唯一。
例如,这在模式中是合法的,但在实践中总是会出现错误
$first/
$second/
例如,当操作路径/test
时,它会生成
Error: "test" matches multiple dynamic bindings "$first" and "$second" (Any)
一个工作示例可能是
$first/
:match [A-Z].*
$second/
:match [^A-Z].*
模式重用
模式的部分可以由可重用的定义构建。
定义是通过使用:def
关键字形成的,后跟其名称和类似于任何其他模式节点的主体
:def reusable/
anything_inside/
它通过在任意其他(相同或更深层)节点内添加:use
标签来使用
reused_here/
:use reusable
可以使用多个:use
标签。属性按照以下顺序解析
example/
## Attributes set here win (before or after any :use lines)
:owner root
## First :use is next in precedence
:use one
## Subsequent :use lines take lower precedence
:use two
依赖关系
~1.5MB
~27K SLoC