Skip to content

part3 - コマンドの実装

前回はユーザーの作成機能について考えた。今回は、コマンドについて考える。

CREATEREADのようなコマンドを実装する必要がある。まずは、前回作成したcreate関数をcreateモジュールに移動しよう。

Create.fsの作成

Create.fs
module create
open System.IO
let counterDirectory = Path.Combine(".", "counter")
let counterFile = Path.Combine(counterDirectory, "counter.txt")
let readCounter =
if File.Exists(counterFile) then
let counter = File.ReadAllText(counterFile)
counter |> int
else
Directory.CreateDirectory(counterDirectory) |> ignore
File.WriteAllText(counterFile, "1") |> ignore
1
let incrementCounter =
let counter = readCounter + 1
File.WriteAllText(counterFile, counter.ToString()) |> ignore
counter
let create =
// まずはコンソールを全消去する。
System.Console.Clear()
Directory.CreateDirectory("./users") |> ignore
printfn "名前を入力してください(1文字以上、150字以内)。"
let name = stdin.ReadLine()
printfn "年齢を入力してください(0以上、150以下)。"
let age = stdin.ReadLine()
printfn "メールアドレスを入力してください(任意)。"
let email = stdin.ReadLine()
let id = incrementCounter
let csvData = sprintf "%d,%s,%s,%s" id name age email
let path = Path.Combine("./users", id.ToString() + ".csv")
File.WriteAllText(path, csvData) |> ignore

fsprojの修正

fsprojファイルにCreate.fsを追加しよう。

// crud.fsproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Create.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
</Project>

オフサイドルールのため、createモジュールをProgram.fsで使うためには、必ず先にCreate.fsをコンパイルする必要がある。

コマンドの実装

次に、Program.fsでCommandの型を定義してみよう。

type Command =
| Create
| Read
| Help
| Unknown of string

本当は他にもいろいろあるのだが、今回はこの3つだけで十分だろう。

入力されたコマンドをparseする関数も作成する。

let parseCommand args =
match args with
| [| "create" |] -> Create
| [| "read" |] -> Read
| [| "--help" |] -> Help
| [| "-h" |] -> Help
| [||] -> Help // コマンドがないときもヘルプを表示
| _ -> Unknown args.[0]

helpをprintするコマンドもついでに作成しておく。

let showHelp =
printfn "Usage: dotnet run [command]"
printfn "Commands:"
printfn " create Create a new user"
printfn " read <ID> Read a user by ID"
printfn " update Update a user by ID"
printfn " delete <ID> Delete a user by ID"
printfn " list List all users"
printfn " --help, -h Show this help"

まだupdateやdelteなどは実装していないが良いことにしよう。

あとは、EntryPointでコマンドをparseして、それに応じた処理を行うようにする。

[<EntryPoint>]
let main argv =
let command = parseCommand argv
match command with
| Create -> create
| Read -> printfn "read"
| Help -> showHelp
| Unknown s -> printfn "Unknown command: %s" s
0

EntryPointとはプログラムの実行を開始する関数のことで、main関数がそれにあたる。argvとはコマンドライン引数のことで、dotnet run createのように実行すると、argvには[| "create" |]が入る。もし、パースできないaaaのようなコマンドが入力された場合は、Unknownとして扱う。

いままでの実装をまとめると、以下のようになる。

open create
type Command =
| Create
| Read
| Help
| Unknown of string
let parseCommand args =
match args with
| [| "create" |] -> Create
| [| "read" |] -> Read
| [| "--help" |] -> Help
| [| "-h" |] -> Help
| [||] -> Help // コマンドがないときもヘルプを表示
| _ -> Unknown args.[0]
let showHelp =
printfn "Usage: dotnet run [command]"
printfn "Commands:"
printfn " create Create a new user"
printfn " read <ID> Read a user by ID"
printfn " update Update a user by ID"
printfn " delete Delete a user by ID"
printfn " list List all users"
printfn " --help, -h Show this help"
[<EntryPoint>]
let main argv =
let command = parseCommand argv
match command with
| Create -> create
| Read -> printfn "read"
| Help -> showHelp
| Unknown s -> printfn "Unknown command: %s" s
0

これで、dotnet run createと実行すると、ユーザーの作成が行われるようになる。 dotnet runだけで実行すると、ヘルプが表示されるようになる。

まとめ

さて、これでコマンドの実装ができた。次回は、ユーザーの読み込み機能を実装していこう。