/// 字符串工具类 - 统一导出接口 /// /// 提供常用的字符串处理功能,包括命名风格转换、注释生成、文本清理等。 /// 本文件作为统一导出接口,实际功能已按职责拆分到子模块: /// - NamingConverter: 命名转换(camelCase, PascalCase, snake_case 等) /// - TextCleaner: 文本清理和格式化 /// - TemplateService: 模板服务(注释生成、文件头生成等) /// /// # 典型用法示例 /// ```dart /// // snake_case 转 camelCase /// StringUtils.toDartPropertyName('user_id'); // userId /// // 含特殊字符 /// StringUtils.toDartPropertyName('user-id'); // userId /// // 数字开头 /// StringUtils.toDartPropertyName('1st_field'); // n1stField /// // 生成注释 /// StringUtils.generateComment('API description'); // /// API description /// ``` /// library; import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart'; import 'package:swagger_generator_flutter/utils/string_utils/template_service.dart'; import 'package:swagger_generator_flutter/utils/string_utils/text_cleaner.dart'; /// 字符串工具类 - 统一导出接口 /// /// 将各子模块的功能聚合到统一的 API 中,保持向后兼容性 class StringUtils { // ==================== 命名转换 (NamingConverter) ==================== /// 转换为 camelCase static String toCamelCase(String input) => NamingConverter.toCamelCase(input); /// 转换为 PascalCase static String toPascalCase(String input) => NamingConverter.toPascalCase(input); /// 转换为 snake_case static String toSnakeCase(String input) => NamingConverter.toSnakeCase(input); /// 转换为符合 Dart 命名规范的属性名 static String toDartPropertyName(String propName) => NamingConverter.toDartPropertyName(propName); /// 生成 Dart 类名 static String generateClassName(String name) => NamingConverter.generateClassName(name); /// 生成常量名称 (UPPER_SNAKE_CASE) static String generateConstantName(String name) => NamingConverter.toConstantCase(name); /// 生成文件名 static String generateFileName(String name) => NamingConverter.generateFileName(name); /// 验证是否为有效的 Dart 标识符 static bool isValidDartIdentifier(String identifier) => NamingConverter.isValidDartIdentifier(identifier); /// 生成枚举值名称 static String generateEnumValueName(dynamic value, int index) => NamingConverter.generateEnumValueName(value, index); /// pluralize 单词 static String pluralize(String word) => NamingConverter.pluralize(word); // ==================== 文本清理 (TextCleaner) ==================== /// 清理描述文本,移除特殊字符和格式化多行注释 static String cleanDescription(String description) => TextCleaner.cleanDescription(description); /// 转义字符串中的特殊字符 static String escapeString(String input) => TextCleaner.escapeString(input); /// 缩进文本 static String indent(String text, int spaces) { final indentation = ' ' * spaces; return text.split('\n').map((line) => '$indentation$line').join('\n'); } /// 截断文本到指定长度 static String truncate(String text, int maxLength, {String suffix = '...'}) => TextCleaner.truncate(text, maxLength, suffix: suffix); /// 标准化文本(移除多余空白和统一换行符) static String normalize(String text) => TextCleaner.normalize(text); // ==================== 模板服务 (TemplateService) ==================== /// 生成注释块 static String generateComment(String text, {bool isBlock = false}) => TemplateService.generateComment(text, isBlock: isBlock); /// 生成文件头注释 static String generateFileHeader( String description, String source, { String? fileName, String? fileType, }) { final service = TemplateService(); return service.generateFileHeader( description, source, fileName: fileName, fileType: fileType, ); } // ==================== 业务逻辑辅助方法 ==================== /// 生成端点名称 static String generateEndpointName(String path, String? operationId) { // 如果有 operationId,优先使用 if (operationId != null && operationId.isNotEmpty) { return toCamelCase(operationId); } // 移除路径中的版本前缀 var cleanPath = path.replaceFirst('/api/v1', ''); // 移除开头的斜杠 if (cleanPath.startsWith('/')) { cleanPath = cleanPath.substring(1); } // 将路径转换为 camelCase final parts = cleanPath.split('/'); if (parts.length >= 2) { final controller = parts[0]; final action = parts[1]; return toCamelCase('${controller}_$action'); } return toCamelCase(cleanPath.replaceAll('/', '_')); } /// 提取控制器名称 static String extractControllerName(ApiPath path) { // 从 tags 中提取控制器名称 if (path.tags.isNotEmpty) { return path.tags.first; } // 从路径中提取控制器名称 final pathParts = path.path.split('/'); if (pathParts.length > 1) { return toPascalCase(pathParts[1]); } return 'General'; } /// 清理路径,保留版本前缀 static String cleanPath(String path) { // 保留版本前缀,只清理其他不必要的字符 return path; } // ==================== 格式化工具 ==================== /// 格式化字节大小 static String formatBytes(int bytes) { if (bytes < 1024) return '${bytes}B'; if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)}KB'; if (bytes < 1024 * 1024 * 1024) { return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB'; } return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB'; } /// 格式化持续时间 static String formatDuration(Duration duration) { if (duration.inMilliseconds >= 1000) { return '${(duration.inMilliseconds / 1000).toStringAsFixed(2)}秒'; } else { return '${duration.inMilliseconds}毫秒'; } } }