🔖
【F#】パスにファイルが存在しなかったらコンパイルエラーにする
概要
F#にはTypeProviderというものがあり、面倒なコード生成無しにコンパイル時にごにょごにょする機能が用意されています。
今回はこちらのパッケージを使用させていただきます。
Tarmil/FSharp.Data.LiteralProviders
TextFile
のEnsureExists
パラメータを利用することで、指定したパスにファイルが存在しなければコンパイルエラーとなります。(本来はテキストファイルの中身を読み取る TypeProvider ですが)
以前お願いしたら実装して頂けました。やったー。
具体例
コード
Path.fs
module Path
let [<Literal>] Image1 = "Images/Image1.png"
let [<Literal>] Image2 = "Images/Image2.png"
let [<Literal>] Sound1 = "Sounds/Sound1.ogg"
#if DEBUG
module private EnsureFilePath =
open FSharp.Data.LiteralProviders
let [<Literal>] Base = "../../Resources/"
do
ignore typeof<
TextFile<const (Base + Image1), EnsureExists=true> *
TextFile<const (Base + Image2), EnsureExists=true> *
TextFile<const (Base + Sound1), EnsureExists=true>
>
#endif
TypeProvider に渡すので、パスはLiteralAttribute
を付けます。const
キーワードを使って、 TypeProvider の引数内でパスの結合ができます。今回はTextFile
で作られた型自体は必要ないので、ignore typeof< (* ... *) >
として捨てています。
プロジェクトファイル
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="Path.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<PackageReference Include="FSharp.Data.LiteralProviders" Version="1.0.3" />
</ItemGroup>
</Project>
DEBUG
ビルド時のみパッケージを参照しています。
プロジェクトの構造
EnsureExistsExample
|--Resources
| |--Images
| | |--Image1.png
| | |--Image2.png
| |--Sounds
| | |--Sound1.png
|--src
| |--Example
| | |--Example.csproj
| | |--Path.fs
| | |--Program.fs
TextFile
に与えた相対パスはプロジェクトファイルから参照されます。
Discussion