import re
from pathlib import Path
from typing import List, Tuple
FILES_TO_PROCESS = [
"crates/openlark-docs/src/base/bitable/v1/app/table/record/get.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/record/batch_get.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/record/batch_create.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/record/batch_update.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/record/batch_delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/field/update.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/field/list.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/field/delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/field/create.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/patch.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/create.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/list.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/view/patch.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/view/list.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/view/get.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/view/delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/view/create.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/form/patch.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/form/get.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/form/field/patch.rs",
"crates/openlark-docs/src/base/bitable/v1/app/table/form/field/list.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/update.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/list.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/create.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/member/list.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/member/delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/member/create.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/member/batch_delete.rs",
"crates/openlark-docs/src/base/bitable/v1/app/role/member/batch_create.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/subscription/patch.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/subscription/create.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/comment/reply/update.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/comment/reply/list.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/comment/reply/delete.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/comment/create.rs",
"crates/openlark-docs/src/ccm/drive/v1/file/comment/batch_query.rs",
]
def fix_validation_imports(content: str) -> Tuple[str, int]:
count = 0
pattern = r'use openlark_core::\s*\{([^}]+)\}'
matches = list(re.finditer(pattern, content, re.MULTILINE | re.DOTALL))
if not matches:
return content, 0
for match in matches:
original_imports = match.group(1)
imports = [item.strip() for item in original_imports.split(',')]
modified = False
new_imports = []
for imp in imports:
if imp == 'validation_error':
modified = True
continue
new_imports.append(imp)
if 'validate_required' not in new_imports:
new_imports.append('validate_required')
modified = True
if modified:
count += 1
new_import_str = ',\n '.join(new_imports)
replacement = f'use openlark_core::\n {{\n {new_import_str}\n}}'
content = content[:match.start()] + replacement + content[match.end():]
return content, count
def fix_validation_calls(content: str) -> Tuple[str, int]:
count = 0
pattern1 = r'if self\.(\w+)\.trim\(\)\.is_empty\(\)\s*\{\s*return Err\(validation_error\([^)]+\)\);\s*\}'
def replace1(match):
nonlocal count
count += 1
field_name = match.group(1)
full_match = match.group(0)
msg_match = re.search(r'"([^"]+)"', full_match)
message = msg_match.group(1) if msg_match else f"{field_name}不能为空"
return f'validate_required!(self.{field_name}.trim(), "{message}");'
content = re.sub(pattern1, replace1, content, flags=re.MULTILINE | re.DOTALL)
pattern2 = r'if self\.(\w+)\.is_empty\(\)\s*\{\s*return Err\(validation_error\([^)]+\)\);\s*\}'
def replace2(match):
nonlocal count
count += 1
field_name = match.group(1)
full_match = match.group(0)
msg_match = re.search(r'"([^"]+)"', full_match)
message = msg_match.group(1) if msg_match else f"{field_name}不能为空"
return f'validate_required!(self.{field_name}, "{message}");'
content = re.sub(pattern2, replace2, content, flags=re.MULTILINE | re.DOTALL)
return content, count
def fix_validation_error_calls(content: str) -> Tuple[str, int]:
count = 0
pattern = r'\bvalidation_error\('
replacement = 'openlark_core::error::validation_error('
new_content, n = re.subn(pattern, replacement, content)
count += n
return new_content, count
def remove_builder_struct(content: str, filename: str) -> Tuple[str, int]:
struct_match = re.search(r'pub struct (\w+Request)\s*\{', content)
if not struct_match:
return content, 0
main_struct_name = struct_match.group(1)
builder_name = f"{main_struct_name}Builder"
builder_pattern = rf'/// .*Builder\s*pub struct {builder_name}\s*{{.*?^}}'
def remove_builder(match):
return ''
new_content, count = re.subn(builder_pattern, remove_builder, content, flags=re.MULTILINE | re.DOTALL)
impl_pattern = rf'impl {builder_name}\s*{{.*?^}}'
def remove_impl(match):
return ''
new_content, impl_count = re.subn(impl_pattern, remove_impl, new_content, flags=re.MULTILINE | re.DOTALL)
return new_content, count + impl_count
def process_file(filepath: str) -> dict:
print(f"处理文件: {filepath}")
try:
with open(filepath, 'r', encoding='utf-8') as f:
original_content = f.read()
content = original_content
changes = {
'filepath': filepath,
'import_fixes': 0,
'validation_fixes': 0,
'validation_error_fixes': 0,
'builder_removed': False,
'modified': False
}
content, count = fix_validation_imports(content)
changes['import_fixes'] = count
if count > 0:
changes['modified'] = True
content, count = fix_validation_calls(content)
changes['validation_fixes'] = count
if count > 0:
changes['modified'] = True
content, count = fix_validation_error_calls(content)
changes['validation_error_fixes'] = count
if count > 0:
changes['modified'] = True
if changes['modified']:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f" ✓ 已修改: 导入({changes['import_fixes']}) 验证({changes['validation_fixes']}) error_fix({changes['validation_error_fixes']})")
else:
print(f" - 无需修改")
return changes
except Exception as e:
print(f" ✗ 错误: {e}")
return {
'filepath': filepath,
'error': str(e),
'modified': False
}
def main():
base_path = Path("/Users/zool/RustroverProjects/open-lark")
print("=" * 80)
print("批量修复验证规范问题")
print("=" * 80)
print()
results = []
for rel_path in FILES_TO_PROCESS:
filepath = base_path / rel_path
if filepath.exists():
result = process_file(str(filepath))
results.append(result)
else:
print(f"文件不存在: {filepath}")
results.append({'filepath': str(filepath), 'error': '文件不存在'})
print()
print("=" * 80)
print("修复总结")
print("=" * 80)
modified_count = sum(1 for r in results if r.get('modified', False))
error_count = sum(1 for r in results if 'error' in r)
print(f"总文件数: {len(results)}")
print(f"已修改: {modified_count}")
print(f"错误: {error_count}")
total_import_fixes = sum(r.get('import_fixes', 0) for r in results)
total_validation_fixes = sum(r.get('validation_fixes', 0) for r in results)
total_error_fixes = sum(r.get('validation_error_fixes', 0) for r in results)
print(f"\n导入修复: {total_import_fixes}")
print(f"验证修复: {total_validation_fixes}")
print(f"error 修复: {total_error_fixes}")
if error_count > 0:
print("\n错误的文件:")
for r in results:
if 'error' in r:
print(f" - {r['filepath']}: {r['error']}")
if __name__ == '__main__':
main()