slumber-python 5.0.0__tar.gz → 5.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. {slumber_python-5.0.0 → slumber_python-5.1.0}/Cargo.lock +11 -11
  2. {slumber_python-5.0.0 → slumber_python-5.1.0}/Cargo.toml +10 -10
  3. {slumber_python-5.0.0 → slumber_python-5.1.0}/PKG-INFO +1 -1
  4. slumber_python-5.1.0/crates/config/src/cereal.rs +75 -0
  5. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/src/lib.rs +3 -4
  6. slumber_python-5.1.0/crates/config/src/tui/cereal.rs +201 -0
  7. slumber_python-5.1.0/crates/config/src/tui/mime.rs +337 -0
  8. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/src/tui/theme.rs +1 -1
  9. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/src/tui.rs +45 -19
  10. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/collection/models.rs +17 -8
  11. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/database/tests.rs +35 -5
  12. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/database.rs +40 -25
  13. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/http/models.rs +8 -15
  14. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/http/tests.rs +8 -4
  15. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/http.rs +17 -2
  16. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/render.rs +3 -3
  17. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/test_util.rs +1 -1
  18. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/src/lib.rs +4 -2
  19. slumber_python-5.0.0/crates/config/src/cereal.rs +0 -275
  20. slumber_python-5.0.0/crates/config/src/tui/mime.rs +0 -199
  21. slumber_python-5.0.0/crates/core/src/http/content_type.rs +0 -159
  22. {slumber_python-5.0.0 → slumber_python-5.1.0}/README.md +0 -0
  23. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/Cargo.toml +0 -0
  24. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/src/default.yml +0 -0
  25. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/src/default_old.yml +0 -0
  26. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/config/src/tui/input.rs +0 -0
  27. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/Cargo.toml +0 -0
  28. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/collection/cereal.rs +0 -0
  29. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/collection/json.rs +0 -0
  30. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/collection/recipe_tree.rs +0 -0
  31. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/collection/schema.rs +0 -0
  32. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/collection.rs +0 -0
  33. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/database/convert.rs +0 -0
  34. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/database/migrations.rs +0 -0
  35. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/http/curl.rs +0 -0
  36. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/lib.rs +0 -0
  37. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/render/functions.rs +0 -0
  38. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/render/tests.rs +0 -0
  39. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/render/util.rs +0 -0
  40. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/core/src/util.rs +0 -0
  41. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/macros/Cargo.toml +0 -0
  42. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/macros/src/lib.rs +0 -0
  43. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/Cargo.toml +0 -0
  44. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/README.md +0 -0
  45. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/dev.py +0 -0
  46. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/mise.toml +0 -0
  47. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/slumber.pyi +0 -0
  48. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/tests/slumber.yml +0 -0
  49. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/tests/test.py +0 -0
  50. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/python/uv.lock +0 -0
  51. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/Cargo.toml +0 -0
  52. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/proptest-regressions/parse.txt +0 -0
  53. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/cereal.rs +0 -0
  54. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/display.rs +0 -0
  55. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/error.rs +0 -0
  56. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/expression.rs +0 -0
  57. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/lib.rs +0 -0
  58. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/parse.rs +0 -0
  59. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/test_util.rs +0 -0
  60. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/tests.rs +0 -0
  61. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/template/src/value.rs +0 -0
  62. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/Cargo.toml +0 -0
  63. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/src/lib.rs +0 -0
  64. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/src/paths.rs +0 -0
  65. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/src/test_util.rs +0 -0
  66. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/src/yaml/error.rs +0 -0
  67. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/src/yaml/resolve.rs +0 -0
  68. {slumber_python-5.0.0 → slumber_python-5.1.0}/crates/util/src/yaml.rs +0 -0
  69. {slumber_python-5.0.0 → slumber_python-5.1.0}/pyproject.toml +0 -0
@@ -809,7 +809,7 @@ dependencies = [
809
809
 
810
810
  [[package]]
811
811
  name = "doc_utils"
812
- version = "5.0.0"
812
+ version = "5.1.0"
813
813
  dependencies = [
814
814
  "anyhow",
815
815
  "clap",
@@ -3280,7 +3280,7 @@ checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
3280
3280
 
3281
3281
  [[package]]
3282
3282
  name = "slumber"
3283
- version = "5.0.0"
3283
+ version = "5.1.0"
3284
3284
  dependencies = [
3285
3285
  "anyhow",
3286
3286
  "console-subscriber",
@@ -3294,7 +3294,7 @@ dependencies = [
3294
3294
 
3295
3295
  [[package]]
3296
3296
  name = "slumber_cli"
3297
- version = "5.0.0"
3297
+ version = "5.1.0"
3298
3298
  dependencies = [
3299
3299
  "anyhow",
3300
3300
  "assert_cmd",
@@ -3329,7 +3329,7 @@ dependencies = [
3329
3329
 
3330
3330
  [[package]]
3331
3331
  name = "slumber_config"
3332
- version = "5.0.0"
3332
+ version = "5.1.0"
3333
3333
  dependencies = [
3334
3334
  "derive_more",
3335
3335
  "dirs",
@@ -3354,7 +3354,7 @@ dependencies = [
3354
3354
 
3355
3355
  [[package]]
3356
3356
  name = "slumber_core"
3357
- version = "5.0.0"
3357
+ version = "5.1.0"
3358
3358
  dependencies = [
3359
3359
  "async-trait",
3360
3360
  "base64 0.22.1",
@@ -3402,7 +3402,7 @@ dependencies = [
3402
3402
 
3403
3403
  [[package]]
3404
3404
  name = "slumber_import"
3405
- version = "5.0.0"
3405
+ version = "5.1.0"
3406
3406
  dependencies = [
3407
3407
  "anyhow",
3408
3408
  "base64 0.22.1",
@@ -3434,7 +3434,7 @@ dependencies = [
3434
3434
 
3435
3435
  [[package]]
3436
3436
  name = "slumber_macros"
3437
- version = "5.0.0"
3437
+ version = "5.1.0"
3438
3438
  dependencies = [
3439
3439
  "proc-macro2",
3440
3440
  "quote",
@@ -3443,7 +3443,7 @@ dependencies = [
3443
3443
 
3444
3444
  [[package]]
3445
3445
  name = "slumber_python"
3446
- version = "5.0.0"
3446
+ version = "5.1.0"
3447
3447
  dependencies = [
3448
3448
  "async-trait",
3449
3449
  "dialoguer",
@@ -3457,7 +3457,7 @@ dependencies = [
3457
3457
 
3458
3458
  [[package]]
3459
3459
  name = "slumber_template"
3460
- version = "5.0.0"
3460
+ version = "5.1.0"
3461
3461
  dependencies = [
3462
3462
  "bytes",
3463
3463
  "derive_more",
@@ -3484,7 +3484,7 @@ dependencies = [
3484
3484
 
3485
3485
  [[package]]
3486
3486
  name = "slumber_tui"
3487
- version = "5.0.0"
3487
+ version = "5.1.0"
3488
3488
  dependencies = [
3489
3489
  "anyhow",
3490
3490
  "async-trait",
@@ -3525,7 +3525,7 @@ dependencies = [
3525
3525
 
3526
3526
  [[package]]
3527
3527
  name = "slumber_util"
3528
- version = "5.0.0"
3528
+ version = "5.1.0"
3529
3529
  dependencies = [
3530
3530
  "derive_more",
3531
3531
  "dirs",
@@ -9,9 +9,9 @@ homepage = "https://slumber.lucaspickering.me"
9
9
  keywords = ["rest", "http", "terminal", "tui"]
10
10
  license = "MIT"
11
11
  repository = "https://github.com/LucasPickering/slumber"
12
- version = "5.0.0"
12
+ version = "5.1.0"
13
13
  # Keep in sync w/ rust-toolchain.toml
14
- rust-version = "1.88.0"
14
+ rust-version = "1.90.0"
15
15
 
16
16
  # Dependencies used in multiple crates get de-duplicated here
17
17
  [workspace.dependencies]
@@ -43,14 +43,14 @@ serde_json = {version = "1.0.120", default-features = false, features = ["preser
43
43
  serde_json_path = "0.7.1"
44
44
  serde_test = "1.0.176"
45
45
  serde_yaml = {version = "0.9.0", default-features = false}
46
- slumber_cli = {path = "./crates/cli", version = "5.0.0" }
47
- slumber_config = {path = "./crates/config", version = "5.0.0", default-features = false }
48
- slumber_core = {path = "./crates/core", version = "5.0.0" }
49
- slumber_import = {path = "./crates/import", version = "5.0.0" }
50
- slumber_macros = {path = "./crates/macros", version = "5.0.0" }
51
- slumber_template = {path = "./crates/template", version = "5.0.0" }
52
- slumber_tui = {path = "./crates/tui", version = "5.0.0" }
53
- slumber_util = {path = "./crates/util", version = "5.0.0" }
46
+ slumber_cli = {path = "./crates/cli", version = "5.1.0" }
47
+ slumber_config = {path = "./crates/config", version = "5.1.0", default-features = false }
48
+ slumber_core = {path = "./crates/core", version = "5.1.0" }
49
+ slumber_import = {path = "./crates/import", version = "5.1.0" }
50
+ slumber_macros = {path = "./crates/macros", version = "5.1.0" }
51
+ slumber_template = {path = "./crates/template", version = "5.1.0" }
52
+ slumber_tui = {path = "./crates/tui", version = "5.1.0" }
53
+ slumber_util = {path = "./crates/util", version = "5.1.0" }
54
54
  strum = {version = "0.27.0", default-features = false}
55
55
  syn = "2.0.101"
56
56
  terminput = "0.5.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slumber-python
3
- Version: 5.0.0
3
+ Version: 5.1.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -0,0 +1,75 @@
1
+ //! Deserialization for config types. Unfortunately these have to be handwritten
2
+ //! to enable the use of saphyr
3
+ //!
4
+ //! We can delete this if
5
+ //! [saphyr-serde](https://docs.rs/saphyr-serde/latest/saphyr_serde/) gets
6
+ //! built.
7
+
8
+ use crate::{Config, HttpEngineConfig};
9
+ use slumber_util::yaml::{
10
+ self, DeserializeYaml, Expected, Field, SourceMap, SourcedYaml,
11
+ StructDeserializer,
12
+ };
13
+
14
+ impl DeserializeYaml for Config {
15
+ fn expected() -> Expected {
16
+ Expected::Mapping
17
+ }
18
+
19
+ fn deserialize(
20
+ mut yaml: SourcedYaml,
21
+ source_map: &SourceMap,
22
+ ) -> yaml::Result<Self> {
23
+ // Drop all fields starting with `.`
24
+ yaml.drop_dot_fields();
25
+
26
+ let default = Self::default();
27
+ let mut deserializer = StructDeserializer::new(yaml)?;
28
+
29
+ let config = Self {
30
+ editor: deserializer
31
+ .get(Field::new("editor").or(default.editor), source_map)?,
32
+ // Both these configs get flattened to the top, so they share the
33
+ // same deserializer
34
+ http: deserialize_http_config(&mut deserializer, source_map)?,
35
+ #[cfg(feature = "tui")]
36
+ tui: crate::tui::deserialize_tui_config(
37
+ &mut deserializer,
38
+ source_map,
39
+ )?,
40
+ };
41
+
42
+ // If we're not running in TUI mode, we know there's still TUI fields
43
+ // in the YAML, so we don't want to fail for those. If all fields are
44
+ // enabled though, extraneous fields should error.
45
+ #[cfg(feature = "tui")]
46
+ {
47
+ deserializer.done()?;
48
+ }
49
+
50
+ Ok(config)
51
+ }
52
+ }
53
+
54
+ /// Deserialize HTTP-specific config fields from an existing deserializer
55
+ fn deserialize_http_config(
56
+ deserializer: &mut StructDeserializer,
57
+ source_map: &SourceMap,
58
+ ) -> yaml::Result<HttpEngineConfig> {
59
+ let default = HttpEngineConfig::default();
60
+ Ok(HttpEngineConfig {
61
+ ignore_certificate_hosts: deserializer.get(
62
+ Field::new("ignore_certificate_hosts")
63
+ .or(default.ignore_certificate_hosts),
64
+ source_map,
65
+ )?,
66
+ large_body_size: deserializer.get(
67
+ Field::new("large_body_size").or(default.large_body_size),
68
+ source_map,
69
+ )?,
70
+ follow_redirects: deserializer.get(
71
+ Field::new("follow_redirects").or(default.follow_redirects),
72
+ source_map,
73
+ )?,
74
+ })
75
+ }
@@ -48,9 +48,9 @@ const DEFAULT_OLD: &str = include_str!("default_old.yml");
48
48
  /// picked up until the app restarts.
49
49
  #[derive(Debug, Default, Serialize)]
50
50
  #[cfg_attr(test, derive(PartialEq))]
51
- #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
52
51
  #[cfg_attr(
53
52
  feature = "schema",
53
+ derive(schemars::JsonSchema),
54
54
  schemars(
55
55
  default,
56
56
  // Allow any top-level property beginning with .
@@ -58,7 +58,7 @@ const DEFAULT_OLD: &str = include_str!("default_old.yml");
58
58
  "^\\.": { "description": "Ignore any property beginning with `.`" }
59
59
  }),
60
60
  example = Config::default(),
61
- )
61
+ ),
62
62
  )]
63
63
  pub struct Config {
64
64
  /// Command to use for in-app editing. If provided, overrides
@@ -235,8 +235,7 @@ impl Config {
235
235
  /// Configuration for the engine that handles HTTP requests
236
236
  #[derive(Debug, Serialize)]
237
237
  #[cfg_attr(test, derive(PartialEq))]
238
- #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
239
- #[cfg_attr(feature = "schema", schemars(default))]
238
+ #[cfg_attr(feature = "schema", derive(schemars::JsonSchema), schemars(default))]
240
239
  pub struct HttpEngineConfig {
241
240
  /// TLS cert errors on these hostnames are ignored. Be careful!
242
241
  pub ignore_certificate_hosts: Vec<String>,
@@ -0,0 +1,201 @@
1
+ //! TUI-specific config deserialization
2
+
3
+ use crate::tui::{Color, CommandsConfig, Syntax, Theme, TuiConfig};
4
+ use serde::de::{self, value::StringDeserializer};
5
+ use slumber_util::yaml::{
6
+ self, DeserializeYaml, Expected, Field, LocatedError, SourceMap,
7
+ SourcedYaml, StructDeserializer,
8
+ };
9
+
10
+ /// Deserialize TUI-specific config fields from an existing deserializer
11
+ pub fn deserialize_tui_config(
12
+ deserializer: &mut StructDeserializer,
13
+ source_map: &SourceMap,
14
+ ) -> yaml::Result<TuiConfig> {
15
+ let default = TuiConfig::default();
16
+ Ok(TuiConfig {
17
+ mime_overrides: deserializer.get(
18
+ Field::new("mime_overrides").or(default.mime_overrides),
19
+ source_map,
20
+ )?,
21
+ commands: deserializer
22
+ .get(Field::new("commands").or(default.commands), source_map)?,
23
+ pager: deserializer
24
+ .get(Field::new("pager").or(default.pager), source_map)?,
25
+ preview_templates: deserializer.get(
26
+ Field::new("preview_templates").or(default.preview_templates),
27
+ source_map,
28
+ )?,
29
+ input_bindings: deserializer.get(
30
+ Field::new("input_bindings").or(default.input_bindings),
31
+ source_map,
32
+ )?,
33
+ theme: deserializer
34
+ .get(Field::new("theme").or(default.theme), source_map)?,
35
+ debug: deserializer
36
+ .get(Field::new("debug").or(default.debug), source_map)?,
37
+ persist: deserializer
38
+ .get(Field::new("persist").or(default.persist), source_map)?,
39
+ })
40
+ }
41
+
42
+ impl DeserializeYaml for CommandsConfig {
43
+ fn expected() -> Expected {
44
+ Expected::Mapping
45
+ }
46
+
47
+ fn deserialize(
48
+ yaml: SourcedYaml,
49
+ source_map: &SourceMap,
50
+ ) -> yaml::Result<Self> {
51
+ let default = Self::default();
52
+ let mut deserializer = StructDeserializer::new(yaml)?;
53
+ let config = Self {
54
+ shell: deserializer
55
+ .get(Field::new("shell").or(default.shell), source_map)?,
56
+ default_query: deserializer.get(
57
+ Field::new("default_query").or(default.default_query),
58
+ source_map,
59
+ )?,
60
+ };
61
+ deserializer.done()?;
62
+ Ok(config)
63
+ }
64
+ }
65
+
66
+ impl DeserializeYaml for Theme {
67
+ fn expected() -> Expected {
68
+ Expected::Mapping
69
+ }
70
+
71
+ fn deserialize(
72
+ yaml: SourcedYaml,
73
+ source_map: &SourceMap,
74
+ ) -> yaml::Result<Self> {
75
+ let default = Self::default();
76
+ let mut deserializer = StructDeserializer::new(yaml)?;
77
+ let config = Self {
78
+ primary_color: deserializer.get(
79
+ Field::new("primary_color").or(default.primary_color),
80
+ source_map,
81
+ )?,
82
+ primary_text_color: deserializer.get(
83
+ Field::new("primary_text_color").or(default.primary_text_color),
84
+ source_map,
85
+ )?,
86
+ secondary_color: deserializer.get(
87
+ Field::new("secondary_color").or(default.secondary_color),
88
+ source_map,
89
+ )?,
90
+ success_color: deserializer.get(
91
+ Field::new("success_color").or(default.success_color),
92
+ source_map,
93
+ )?,
94
+ error_color: deserializer.get(
95
+ Field::new("error_color").or(default.error_color),
96
+ source_map,
97
+ )?,
98
+ text_color: deserializer.get(
99
+ Field::new("text_color").or(default.text_color),
100
+ source_map,
101
+ )?,
102
+ background_color: deserializer.get(
103
+ Field::new("background_color").or(default.background_color),
104
+ source_map,
105
+ )?,
106
+ border_color: deserializer.get(
107
+ Field::new("border_color").or(default.border_color),
108
+ source_map,
109
+ )?,
110
+ disabled_color: deserializer.get(
111
+ Field::new("disabled_color").or(default.disabled_color),
112
+ source_map,
113
+ )?,
114
+ hint_text_color: deserializer.get(
115
+ Field::new("hint_text_color").or(default.hint_text_color),
116
+ source_map,
117
+ )?,
118
+ text_box_background_color: deserializer.get(
119
+ Field::new("text_box_background_color")
120
+ .or(default.text_box_background_color),
121
+ source_map,
122
+ )?,
123
+ alternate_row_background_color: deserializer.get(
124
+ Field::new("alternate_row_background_color")
125
+ .or(default.alternate_row_background_color),
126
+ source_map,
127
+ )?,
128
+ alternate_row_text_color: deserializer.get(
129
+ Field::new("alternate_row_text_color")
130
+ .or(default.alternate_row_text_color),
131
+ source_map,
132
+ )?,
133
+ syntax: deserializer
134
+ .get(Field::new("syntax").or(default.syntax), source_map)?,
135
+ };
136
+ deserializer.done()?;
137
+ Ok(config)
138
+ }
139
+ }
140
+
141
+ impl DeserializeYaml for Syntax {
142
+ fn expected() -> Expected {
143
+ Expected::Mapping
144
+ }
145
+
146
+ fn deserialize(
147
+ yaml: SourcedYaml,
148
+ source_map: &SourceMap,
149
+ ) -> yaml::Result<Self> {
150
+ let default = Self::default();
151
+ let mut deserializer = StructDeserializer::new(yaml)?;
152
+ let config = Self {
153
+ comment_color: deserializer.get(
154
+ Field::new("comment_color").or(default.comment_color),
155
+ source_map,
156
+ )?,
157
+ builtin_color: deserializer.get(
158
+ Field::new("builtin_color").or(default.builtin_color),
159
+ source_map,
160
+ )?,
161
+ escape_color: deserializer.get(
162
+ Field::new("escape_color").or(default.escape_color),
163
+ source_map,
164
+ )?,
165
+ number_color: deserializer.get(
166
+ Field::new("number_color").or(default.number_color),
167
+ source_map,
168
+ )?,
169
+ string_color: deserializer.get(
170
+ Field::new("string_color").or(default.string_color),
171
+ source_map,
172
+ )?,
173
+ special_color: deserializer.get(
174
+ Field::new("special_color").or(default.special_color),
175
+ source_map,
176
+ )?,
177
+ };
178
+ deserializer.done()?;
179
+ Ok(config)
180
+ }
181
+ }
182
+
183
+ impl DeserializeYaml for Color {
184
+ fn expected() -> Expected {
185
+ Expected::String
186
+ }
187
+
188
+ fn deserialize(
189
+ yaml: SourcedYaml,
190
+ _source_map: &SourceMap,
191
+ ) -> yaml::Result<Self> {
192
+ let location = yaml.location;
193
+ let s = yaml.try_into_string()?;
194
+ // Use ratatui's serde implementation
195
+ <ratatui_core::style::Color as de::Deserialize>::deserialize(
196
+ StringDeserializer::new(s),
197
+ )
198
+ .map(Color::from)
199
+ .map_err(|error: de::value::Error| LocatedError::other(error, location))
200
+ }
201
+ }