controlmap_parser/lib.rs
1#![allow(clippy::tabs_in_doc_comments)] // <- controlmap.txt ignores clippy's caution because tab is part of the language use.
2//! # ControlMap Parser Library
3//!
4//! The controlmap.txt parser for Skyrim.
5//!
6//! ## features
7//!
8//! - [x] controlmap.txt => json structure
9//! - [x] json structure => controlmap.txt
10//! - [x] Analysis using enum scanCodes.
11//!
12//! # Examples
13//!
14//! ```rust
15//! use controlmap_parser::ControlMap;
16//!
17//! type Result<T, E = Box<dyn std::error::Error + 'static>> = core::result::Result<T, E>;
18//! fn main() -> Result<()> {
19//! let input = r#"
20//! // Lockpicking
21//! RotatePick 0xff 0xa 0x000b 0 0 0 0x8
22//! RotateLock 0x1e,0xff 0xff 0x000c 0 0 0 0x8
23//! DebugMode 0x35 0xff 0x4000 0 0 0 0x8
24//! Cancel 0x0f 0xff 0x1000 0 0 0 0x8
25//!
26//! // Favor
27//! Cancel 0x0f 0xff 0x1000 0 0 0 0x108"#;
28//!
29//! let control_map = ControlMap::from_txt(input)?;
30//! println!("txt => Struct:\n{:?}", &control_map);
31//!
32//! let json = serde_json::to_string_pretty(&control_map)?;
33//! let expected_json = r#"{
34//! "lines": [
35//! "BlankLine",
36//! {
37//! "Comment": " Lockpicking"
38//! },
39//! {
40//! "EventLine": {
41//! "event_name": "RotatePick",
42//! "keyboard_id": {
43//! "One": "0xff"
44//! },
45//! "mouse_id": {
46//! "One": "0xa"
47//! },
48//! "gamepad_id": {
49//! "One": "0x000b"
50//! },
51//! "remap_key": false,
52//! "remap_mouse": false,
53//! "remap_gamepad": false,
54//! "event_binary_flag": "0x8"
55//! }
56//! },
57//! {
58//! "EventLine": {
59//! "event_name": "RotateLock",
60//! "keyboard_id": {
61//! "Or": [
62//! {
63//! "One": "0x1e"
64//! },
65//! {
66//! "One": "0xff"
67//! }
68//! ]
69//! },
70//! "mouse_id": {
71//! "One": "0xff"
72//! },
73//! "gamepad_id": {
74//! "One": "0x000c"
75//! },
76//! "remap_key": false,
77//! "remap_mouse": false,
78//! "remap_gamepad": false,
79//! "event_binary_flag": "0x8"
80//! }
81//! },
82//! {
83//! "EventLine": {
84//! "event_name": "DebugMode",
85//! "keyboard_id": {
86//! "One": "0x35"
87//! },
88//! "mouse_id": {
89//! "One": "0xff"
90//! },
91//! "gamepad_id": {
92//! "One": "0x4000"
93//! },
94//! "remap_key": false,
95//! "remap_mouse": false,
96//! "remap_gamepad": false,
97//! "event_binary_flag": "0x8"
98//! }
99//! },
100//! {
101//! "EventLine": {
102//! "event_name": "Cancel",
103//! "keyboard_id": {
104//! "One": "0x0f"
105//! },
106//! "mouse_id": {
107//! "One": "0xff"
108//! },
109//! "gamepad_id": {
110//! "One": "0x1000"
111//! },
112//! "remap_key": false,
113//! "remap_mouse": false,
114//! "remap_gamepad": false,
115//! "event_binary_flag": "0x8"
116//! }
117//! },
118//! "BlankLine",
119//! {
120//! "Comment": " Favor"
121//! },
122//! {
123//! "EventLine": {
124//! "event_name": "Cancel",
125//! "keyboard_id": {
126//! "One": "0x0f"
127//! },
128//! "mouse_id": {
129//! "One": "0xff"
130//! },
131//! "gamepad_id": {
132//! "One": "0x1000"
133//! },
134//! "remap_key": false,
135//! "remap_mouse": false,
136//! "remap_gamepad": false,
137//! "event_binary_flag": "0x108"
138//! }
139//! }
140//! ]
141//! }"#;
142//! assert_eq!(&json, expected_json);
143//!
144//! let control_map: ControlMap = serde_json::from_str(&json)?;
145//! // Yes, blank lines are not removed, they are applied as is.
146//! // There are places where it would be an error to do otherwise.
147//! let formatted_control_map = r#"
148//! // Lockpicking
149//! RotatePick 0xff 0xa 0x000b 0 0 0 0x8
150//! RotateLock 0x1e+0xff 0xff 0x000c 0 0 0 0x8
151//! DebugMode 0x35 0xff 0x4000 0 0 0 0x8
152//! Cancel 0x0f 0xff 0x1000 0 0 0 0x8
153//!
154//! // Favor
155//! Cancel 0x0f 0xff 0x1000 0 0 0 0x108
156//! "#;
157//! assert_eq!(control_map.to_string(), formatted_control_map);
158//!
159//! Ok(())
160//! }
161//! ```
162
163mod controlmap;
164pub mod parser;
165pub mod scan_code;
166
167pub use controlmap::{ControlMap, ControlMapError};