typub_adapter_hashnode/
config.rs1use anyhow::Result;
2
3use typub_adapters_core::{
4 AdapterCapability, AdapterRegistrar, NodePolicy, NodePolicyAction, PlatformAdapter,
5 TaxonomyCapability, resolve_asset_strategy_from_config,
6};
7use typub_config::{Config, PlatformConfig};
8use typub_core::{
9 AssetStrategy, CapabilityGapBehavior, CapabilitySupport, MathDelimiters, MathRendering,
10};
11
12use crate::adapter::HashnodeAdapter;
13
14pub const ID: &str = "hashnode";
15
16pub const CAPABILITY: AdapterCapability = AdapterCapability {
17 id: ID,
18 name: "Hashnode",
19 short_code: "hn",
20 local_output: false,
21 requires_config: true,
22 taxonomy: TaxonomyCapability::new(
23 CapabilitySupport::Supported,
24 CapabilitySupport::Unsupported(CapabilityGapBehavior::WarnAndDegrade),
25 CapabilitySupport::Supported,
26 typub_core::DraftSupport::SeparateObjects,
27 ),
28 asset_strategies: &[AssetStrategy::External],
29 math_renderings: &[MathRendering::Latex], math_delimiters: &[MathDelimiters::Brackets],
31 code_highlight: true,
32 notes: "Tags synced (max 5); internal links resolved from local status DB. Math via MathJax.",
33 node_policy: NodePolicy {
34 raw: NodePolicyAction::Sanitize,
35 unknown: NodePolicyAction::Drop,
36 },
37};
38
39pub fn resolve_strategy(platform_config: Option<&PlatformConfig>) -> Result<AssetStrategy> {
40 resolve_asset_strategy_from_config(platform_config, &CAPABILITY)
41}
42
43pub fn create(config: &Config) -> Result<Box<dyn PlatformAdapter>> {
44 Ok(Box::new(HashnodeAdapter::new(config)?))
45}
46
47pub fn register(registrar: &mut AdapterRegistrar) -> Result<()> {
48 registrar.register_factory(ID, create)?;
49 registrar.register_capability(ID, CAPABILITY)?;
50 Ok(())
51}
52
53#[cfg(test)]
54#[allow(clippy::expect_used)]
55mod tests {
56 use super::*;
57 use std::collections::HashMap;
58
59 #[test]
60 fn test_resolve_strategy_default() {
61 let result = resolve_strategy(None).expect("resolve");
62 assert_eq!(result, AssetStrategy::External);
63 }
64
65 #[test]
66 fn test_resolve_strategy_invalid_value() {
67 let cfg = PlatformConfig {
68 enabled: true,
69 asset_strategy: Some("invalid".into()),
70 published: None,
71 theme: None,
72 internal_link_target: None,
73 math_rendering: None,
74 math_delimiters: None,
75 extra: HashMap::new(),
76 };
77 let err = resolve_strategy(Some(&cfg)).expect_err("invalid should fail");
78 assert!(err.to_string().contains("Invalid asset strategy"));
79 }
80
81 #[test]
82 fn test_resolve_strategy_disabled_platform() {
83 let cfg = PlatformConfig {
84 enabled: false,
85 asset_strategy: Some("external".into()),
86 published: None,
87 theme: None,
88 internal_link_target: None,
89 math_rendering: None,
90 math_delimiters: None,
91 extra: HashMap::new(),
92 };
93 let result = resolve_strategy(Some(&cfg)).expect("resolve");
94 assert_eq!(result, AssetStrategy::External);
95 }
96
97 #[test]
98 fn test_resolve_strategy_unsupported() {
99 let cfg = PlatformConfig {
100 enabled: true,
101 asset_strategy: Some("upload".into()),
102 published: None,
103 theme: None,
104 internal_link_target: None,
105 math_rendering: None,
106 math_delimiters: None,
107 extra: HashMap::new(),
108 };
109 let err = resolve_strategy(Some(&cfg)).expect_err("should fail");
110 assert!(err.to_string().contains("does not support"));
111 }
112}