1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*!
Implementation of the UTF table format used in CRIWARE CPK files.
This crate primarily offers the [`utf_table`] macro, which automatically
creates a table read and write procedure based on a schema provided as a
struct definition (see the [`Table`] trait for more info on what is provided,
and the macro itself for info on how to write the schema).
```
#[utf_table]
struct Table {
#[column_name = "ColumnName"]
#[rowed]
rowed_value: i64,
#[constant]
constant_value: String,
#[optional]
#[rowed]
rowed_optional_value: i8,
}
```
The [`Schema`] type (unrelated to `utf_table`) allows for retrieving
the structure of a table *without its contents*. This can be useful
for debugging, or any situation where a table may be one of many possible
schemas (see example).
The [`Packet`] type mimics the method in which the primary tables in a CPK
file are stored. Encryption and decryption are handled automatically.
The [`Reader`] and [`Writer`] types are also available for use in custom
read/write procedures, but they are, in their current state, highly
specialized for the [`utf_table`] macro, so using them is
**not recommended**.
# Examples
This section demonstrates important features this crate provides. Each example
can be dropped in to a project and compile (and run if you had the necessary
table files).
All of these examples demonstrate high-level functionality. For more precise
examples and explanations, consult the page for the relevant type/macro.
## Example: Basic table read/write
```
use criware_utf::{Table, utf_table};
#[utf_table]
struct ImportantTable {
#[column_name = "ID"]
id: i64,
file_name: String,
#[constant]
comment: String,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut orig = std::fs::File::open("important-table.bin")?;
let mut new = std::fs::File::create("more-important-table.bin")?;
let mut table = ImportantTable::read(&mut orig)?;
for row in &table.rows {
println!("\"{}\" (id {})", row.file_name, row.id);
}
table.constants.comment = format!("\"{}\" -loser", table.constants.comment);
table.write(&mut new)?;
Ok(())
}
```
## Example: Reading one of many schemas
```
use std::io::{Seek, SeekFrom};
use criware_utf::{Schema, Table, utf_table};
#[utf_table(table_name = "CoolTable")]
struct CoolTableV1 {
id: i64,
name: String,
}
#[utf_table(table_name = "CoolTable")]
struct CoolTableV2 {
id: i64,
name: String,
#[column_name = "Crc32"]
crc: u32,
}
enum CoolTable {
V1(CoolTableV1),
V2(CoolTableV2),
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut file = std::fs::File::open("table.bin")?;
let schema = Schema::read(&mut file)?;
let table = {
file.seek(SeekFrom::Start(0))?;
if schema.has_column("Crc32") {
CoolTable::V2(CoolTableV2::read(&mut file)?)
} else {
CoolTable::V1(CoolTableV1::read(&mut file)?)
}
};
// ... do something ...
Ok(())
}
```
*/
pub use *;
extern crate criware_utf_macros;
pub use utf_table;