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
// ---------------- [ File: capability-example/src/store_failed_snippet.rs ]
crate::ix!();
pub fn store_failed_snippet(
fail_dir: &PathBuf,
type_name: &str,
snippet_text: &str,
) -> std::io::Result<PathBuf> {
std::fs::create_dir_all(fail_dir)?;
let base_name = format!(
"{}-parse-failure",
type_name
.to_lowercase()
.replace(' ', "-")
.replace('_', "-")
);
// find next free index
let mut index = 0;
loop {
let candidate = fail_dir.join(format!("{}{}.json", base_name, index));
if !candidate.exists() {
// write snippet
std::fs::write(&candidate, snippet_text)?;
return Ok(candidate);
}
index += 1;
}
}
/// Tries to parse the raw clipboard as type T.
/// Returns:
/// Ok(Some(value)) if parse succeeded,
/// Ok(None) if it wasn't valid at all for that type (like a total JSON parse fail),
/// Err(()) if it was valid JSON but fuzzy parse failed => we store it in fail-dir.
pub fn attempt_snippet_parse<T: FuzzyFromJsonValue>(
raw_clipboard: &str,
type_name: &str,
fail_dir: Option<&PathBuf>,
) -> Result<Option<T>, ()> {
// 1) Attempt raw JSON parse
let parsed_json: serde_json::Value = match serde_json::from_str(raw_clipboard) {
Ok(val) => val,
Err(_e) => {
// It's not even valid JSON => definitely not parseable as T => return Ok(None)
return Ok(None);
}
};
// 2) Attempt fuzzy parse
match T::fuzzy_from_json_value(&parsed_json) {
Ok(obj) => {
// Full success
Ok(Some(obj))
}
Err(ffve) => {
// Fuzzy parse error => let's store it if the user gave fail_dir
if let Some(dir) = fail_dir {
match store_failed_snippet(dir, type_name, raw_clipboard) {
Ok(path) => warn!("Wrote fuzzy-parse failure snippet to {path:?}"),
Err(e) => warn!("Unable to store fuzzy-parse failure snippet: {e}"),
}
}
Err(())
}
}
}