๐Ÿ“ฆ sleepyfran / duets

๐Ÿ“„ Song.Types.fs ยท 72 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72namespace Duets.Entities

open FSharp.Data.UnitSystems.SI.UnitNames

[<AutoOpen>]
module SongTypes =
    /// Unique identifier of a song.
    type SongId = SongId of Identity

    /// Defines the different styles of vocals that a song can have.
    type VocalStyle =
        | Instrumental
        | Normal
        | Growl
        | Screamo

    /// Length of a song or an album as minutes and seconds.
    type Length =
        { Minutes: int<minute>
          Seconds: int<second> }

    [<Measure>]
    type practice

    type Practice = int<practice>

    /// Defines a song composed by a band in its most basic form, there's more
    /// specific types depending on the type of information we want to query.
    type Song =
        { Id: SongId
          Name: string
          Length: Length
          VocalStyle: VocalStyle
          Practice: Practice }

    /// Defines a song that has been started but not finished yet. It accepts
    /// a generic parameter so that we can hold either the entire song object
    /// or just the ID.
    type Unfinished<'s> =
        | Unfinished of song: 's * max: MaxQuality * current: Quality

    /// Defines a song that has been finished and can be recorded and played live.
    type Finished<'s> = Finished of song: 's * quality: Quality

    /// Defines a song that has been finished with whether it has been recorded
    /// or not.
    type FinishedWithMetadata<'s> =
        | FinishedWithMetadata of
            song: Finished<'s> *
            recorded: bool *
            finishDate: Date

    /// Defines a song that has been recorded and can be played live.
    type Recorded<'s> = Recorded of song: 's * totalQuality: Quality

    /// Indicates whether the song can be further improved or if it has reached its
    /// maximum quality and thus cannot be improved. All variants wrap an int that
    /// hold the current value.
    type SongStatus =
        | CanBeImproved
        | ReachedMaxQualityInLastImprovement
        | ReachedMaxQualityAlready

    /// Collection of songs (either finished or unfinished) by a band.
    type SongsByBand<'song> = Map<BandId, Map<SongId, 'song>>

    /// Represents the repertoire of a band with its unfinished and finished songs.
    /// Only finished songs can be recorded and played live.
    type BandSongRepertoire =
        { UnfinishedSongs: SongsByBand<Unfinished<Song>>
          FinishedSongs: SongsByBand<FinishedWithMetadata<Song>> }