pub const SUPPORTED_BASIC_TYPES: &[&str] = &[
"String", "str", "&str", "i8", "i16", "i32", "i64", "i128", "isize",
"u8", "u16", "u32", "u64", "u128", "usize", "f32", "f64", "bool",
];
pub const COMMON_NODE_TYPES: &[&str] = &[
"paragraph", "heading", "text", "image", "link", "list", "list_item", "table", "table_row", "table_cell", "code_block", "blockquote", "horizontal_rule", ];
pub const COMMON_MARK_TYPES: &[&str] = &[
"bold", "italic", "underline", "strikethrough", "code", "link", "color", "background", "font_size", "font_family", ];
pub mod required_attributes {
pub const NODE_REQUIRED: &[&str] = &[
"node_type", ];
pub const MARK_REQUIRED: &[&str] = &[
"mark_type", ];
}
pub mod optional_attributes {
pub const NODE_OPTIONAL: &[&str] = &[
"marks", "content", ];
pub const MARK_OPTIONAL: &[&str] = &[
];
pub const FIELD_ATTRIBUTES: &[&str] = &[
"attr", ];
}
pub mod error_messages {
pub const MISSING_ATTRIBUTE_TEMPLATE: &str =
"缺少必需的宏属性: {attribute}";
pub const INVALID_ATTRIBUTE_VALUE_TEMPLATE: &str =
"无效的属性值 '{value}' 用于属性 '{attribute}': {reason}";
pub const UNSUPPORTED_FIELD_TYPE_TEMPLATE: &str =
"不支持的字段类型 '{field_type}' 在字段 '{field_name}' 中";
pub const PARSE_ERROR_TEMPLATE: &str = "属性解析错误: {message}";
pub const GENERATION_ERROR_TEMPLATE: &str = "代码生成错误: {message}";
pub const VALIDATION_ERROR_TEMPLATE: &str = "验证错误: {message}";
}
pub mod suggestion_templates {
pub const MISSING_NODE_TYPE_SUGGESTION: &str = "请在结构体上添加 #[node_type = \"类型名\"] 属性,例如: #[node_type = \"paragraph\"]";
pub const MISSING_MARK_TYPE_SUGGESTION: &str = "请在结构体上添加 #[mark_type = \"类型名\"] 属性,例如: #[mark_type = \"bold\"]";
pub const INVALID_ATTRIBUTE_VALUE_SUGGESTION: &str =
"请检查属性值格式是否正确,确保使用双引号包围字符串值";
pub const UNSUPPORTED_FIELD_TYPE_SUGGESTION: &str = "请使用支持的基本类型:String, i32, i64, f32, f64, bool 或其 Option 包装版本";
pub const GENERAL_SUGGESTION: &str = "请检查宏的使用方式是否符合文档要求";
}
pub mod defaults {
pub const DEFAULT_NODE_CONTENT: &str = "*";
pub const DEFAULT_ATTRS_CAPACITY: usize = 4;
pub const DEFAULT_MARKS_SEPARATOR: &str = ",";
}
pub mod codegen {
pub const NODE_CONVERTER_METHOD: &str = "to_node";
pub const MARK_CONVERTER_METHOD: &str = "to_mark";
pub const NODE_INSTANCE_VAR: &str = "node";
pub const MARK_INSTANCE_VAR: &str = "mark";
pub const NODE_SPEC_VAR: &str = "node_spec";
pub const MARK_SPEC_VAR: &str = "mark_spec";
pub const ATTRS_MAP_VAR: &str = "attrs";
}
pub mod documentation {
pub const NODE_CONVERTER_DOC: &str = "将结构体转换为 mf_core::node::Node 实例\n\
\n\
此方法由 #[derive(Node)] 宏自动生成,\n\
根据结构体的字段和宏属性配置创建相应的 Node 实例。";
pub const MARK_CONVERTER_DOC: &str = "将结构体转换为 mf_core::mark::Mark 实例\n\
\n\
此方法由 #[derive(Mark)] 宏自动生成,\n\
根据结构体的字段和宏属性配置创建相应的 Mark 实例。";
pub const RETURN_VALUE_DOC: &str = "# 返回值\n\
\n\
返回配置好的实例";
pub const EXAMPLE_DOC: &str = "# 示例\n\
\n\
```rust\n\
// 创建实例\n\
let instance = MyStruct { /* 字段初始化 */ };\n\
// 转换为相应类型\n\
let converted = instance.to_node(); // 或 to_mark()\n\
```";
}
pub mod validation {
pub const MIN_IDENTIFIER_LENGTH: usize = 1;
pub const MAX_IDENTIFIER_LENGTH: usize = 100;
pub const MAX_ATTRIBUTE_VALUE_LENGTH: usize = 256;
pub const MAX_MARKS_COUNT: usize = 10;
pub const MAX_FIELD_ATTRIBUTES: usize = 100;
}
pub mod performance {
pub const TYPE_ANALYSIS_CACHE_SIZE: usize = 100;
pub const CODEGEN_CACHE_SIZE: usize = 50;
pub const BATCH_PROCESS_THRESHOLD: usize = 5;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[allow(clippy::const_is_empty)]
fn test_supported_basic_types() {
assert!(SUPPORTED_BASIC_TYPES.contains(&"String"));
assert!(SUPPORTED_BASIC_TYPES.contains(&"i32"));
assert!(SUPPORTED_BASIC_TYPES.contains(&"f64"));
assert!(SUPPORTED_BASIC_TYPES.contains(&"bool"));
assert!(!SUPPORTED_BASIC_TYPES.is_empty());
}
#[test]
#[allow(clippy::const_is_empty)]
fn test_common_node_types() {
assert!(COMMON_NODE_TYPES.contains(&"paragraph"));
assert!(COMMON_NODE_TYPES.contains(&"heading"));
assert!(COMMON_NODE_TYPES.contains(&"text"));
assert!(!COMMON_NODE_TYPES.is_empty());
}
#[test]
#[allow(clippy::const_is_empty)]
fn test_common_mark_types() {
assert!(COMMON_MARK_TYPES.contains(&"bold"));
assert!(COMMON_MARK_TYPES.contains(&"italic"));
assert!(COMMON_MARK_TYPES.contains(&"code"));
assert!(!COMMON_MARK_TYPES.is_empty());
}
#[test]
fn test_required_attributes() {
assert!(required_attributes::NODE_REQUIRED.contains(&"node_type"));
assert!(required_attributes::MARK_REQUIRED.contains(&"mark_type"));
}
#[test]
fn test_optional_attributes() {
assert!(optional_attributes::NODE_OPTIONAL.contains(&"marks"));
assert!(optional_attributes::NODE_OPTIONAL.contains(&"content"));
assert!(optional_attributes::FIELD_ATTRIBUTES.contains(&"attr"));
}
#[test]
fn test_error_message_templates() {
assert!(
error_messages::MISSING_ATTRIBUTE_TEMPLATE.contains("{attribute}")
);
assert!(
error_messages::INVALID_ATTRIBUTE_VALUE_TEMPLATE
.contains("{value}")
);
assert!(
error_messages::UNSUPPORTED_FIELD_TYPE_TEMPLATE
.contains("{field_type}")
);
}
#[test]
#[allow(clippy::const_is_empty)]
fn test_suggestion_templates() {
assert!(
suggestion_templates::MISSING_NODE_TYPE_SUGGESTION
.contains("node_type")
);
assert!(
suggestion_templates::MISSING_MARK_TYPE_SUGGESTION
.contains("mark_type")
);
assert!(!suggestion_templates::GENERAL_SUGGESTION.is_empty());
}
#[test]
fn test_codegen_constants() {
assert_eq!(codegen::NODE_CONVERTER_METHOD, "to_node");
assert_eq!(codegen::MARK_CONVERTER_METHOD, "to_mark");
assert_eq!(codegen::NODE_INSTANCE_VAR, "node");
assert_eq!(codegen::MARK_INSTANCE_VAR, "mark");
}
#[test]
#[allow(clippy::assertions_on_constants, clippy::const_is_empty)]
fn test_validation_constants() {
assert!(validation::MIN_IDENTIFIER_LENGTH > 0);
assert!(
validation::MAX_IDENTIFIER_LENGTH
> validation::MIN_IDENTIFIER_LENGTH
);
assert!(validation::MAX_MARKS_COUNT > 0);
assert!(validation::MAX_FIELD_ATTRIBUTES > 0);
}
#[test]
#[allow(clippy::assertions_on_constants)]
fn test_performance_constants() {
assert!(performance::TYPE_ANALYSIS_CACHE_SIZE > 0);
assert!(performance::CODEGEN_CACHE_SIZE > 0);
assert!(performance::BATCH_PROCESS_THRESHOLD > 0);
}
}