Rust로 CLI 도구 만들며 배운 것들

배경

배포 스크립트가 bash로 작성되어 있었는데, 점점 복잡해지면서 유지보수가 어려워졌다. Python도 고려했지만 바이너리 배포를 원했고, Go는 이미 다른 팀에서 쓰고 있어서 Rust를 선택했다.

소유권과의 첫 만남

처음엔 컴파일러가 계속 에러를 뱉어냈다. 특히 String을 여러 함수에 넘기다가 move 에러를 마주쳤다.

fn process_config(config: String) {
    validate(&config);
    execute(config); // error: value borrowed here after move
}

해결은 간단했다. 참조자를 사용하거나 clone()을 쓰면 됐다.

fn process_config(config: &str) {
    validate(config);
    execute(config);
}

실용적인 크레이트들

  • clap: CLI 인자 파싱. derive 매크로로 간결하게 정의 가능
  • tokio: 비동기 런타임. API 호출할 때 필요했음
  • serde: JSON 직렬화. 타입 안전하게 처리됨
  • anyhow: 에러 핸들링. Result 타입 다루기 편해짐

느낀 점

컴파일 시간이 길지만, 컴파일만 되면 런타임 에러가 거의 없다. 타입 시스템이 강력해서 리팩토링할 때 안심이 된다.

Node.js처럼 빠르게 프로토타입을 만들긴 어렵지만, 안정성이 중요한 도구를 만들 때는 좋은 선택이었다. 바이너리 하나로 배포되는 것도 장점이다.

팀원들 반응도 괜찮아서 다음엔 좀 더 큰 프로젝트에 적용해볼 생각이다.