SAFE Stack の ToDo アプリはデータを保存できるようにする続き。

目的の処理を実装する前に、ユーティリティー的な関数を実装した。 実装先のファイルは新しく 1 個追加して src/Server/ServerUtil.fs にする。 汎用的な処理はアプリケーション固有のそれと分けるのがよいと思うので、 src/Server/Server.fs と別のファイルにした。

src/Server/ServerUtil.fs

namespace ServerUtil

module StringUtil =
    open System.Text.RegularExpressions
    let stripHead s = Regex("^\s+").Replace(s, "")
    let stripTail s = Regex("\s+$").Replace(s, "")
    let strip = stripHead >> stripTail

module EnvUtil =
    open System
    let getEnv name = name |> Environment.GetEnvironmentVariable |> string

module IoUtil =
    open System
    open System.IO

    let docRoot () = Environment.GetFolderPath Environment.SpecialFolder.Personal
    let dirSepChar = Path.DirectorySeparatorChar
    let dirSepStr  = string dirSepChar
    let isAbsPath (path: string) = path.Length > 0 && path.[0] = dirSepChar

    let checkFile (filePath: string) =
        File.Exists filePath

    let assureDir (dirPath: string) =
        // Memo:
        //   - "Directory.CreateDirectory" is almost equivalent to "mkdir -p"
        Directory.CreateDirectory dirPath |> ignore

いくつか補足する。

Environment.GetEnvironmentVariable は対象の環境変数が不在のときに、 null を返してくる。 この挙動は順当だけど、 F# の文字列で null の可能性を意識するのは嫌過ぎるので、ここでは string 関数に渡して空文字列にしてしまっている。 string option 型にして null のときは None にする方法もあるけど、環境変数を扱うときは未定義と空文字列と区別しないことが多いと思うので string 型に丸めてしまった。

Environment.GetFolderPath Environment.SpecialFolder.Personal は Unix 系の環境ではホームディレクトリを返してくれた。 Windows 環境ではマイドキュメントになるらしい。

Path.DirectorySeparatorChar はパスの区切り文字で、 Unix 系の環境では当然 ='/'= が返される。 Windows 環境では ='/'= になるのだろう。