Skip to content

Instantly share code, notes, and snippets.

@sheridanchris
Last active March 16, 2024 13:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save sheridanchris/788cfe00fdd3ebeba9fb81620e4b11a3 to your computer and use it in GitHub Desktop.
Save sheridanchris/788cfe00fdd3ebeba9fb81620e4b11a3 to your computer and use it in GitHub Desktop.
open Donald
open System.Data.Common
open System.Data.SQLite
open System.Threading.Tasks
open Giraffe
open Giraffe.ViewEngine
open FsToolkit.ErrorHandling
open Microsoft.AspNetCore.Builder
[<RequireQualifiedAccess>]
type EmailAddress =
| Private
| Public of string
type PublicUserInformation = {
Id: int
Username: string
EmailAddress: EmailAddress
}
module User =
let read (reader: DbDataReader) = {
Id = reader.ReadInt32 "id"
Username = reader.ReadString "username"
EmailAddress =
match reader.ReadBoolean "is_email_visible" with
| true -> EmailAddress.Public(reader.ReadString "email_address")
| false -> EmailAddress.Private
}
let queryUserById id =
use connection = new SQLiteConnection("Data Source=local.db")
let query = "select * from users where id = @id"
connection
|> Db.newCommand query
|> Db.setParams [ "id", SqlType.Int id ]
|> Db.Async.querySingle User.read
let userNotFoundView = main [] [ p [] [ str "This user does not exist :(" ] ]
let userView user =
main [] [
p [] [ str $"User ID: {user.Id}" ]
p [] [ str $"Username: {user.Username}" ]
match user.EmailAddress with
| EmailAddress.Private -> p [] [ str "This user has a private email address" ]
| EmailAddress.Public email -> p [] [ str $"Email address: {email}" ]
]
let renderUserOrNotFound potentialUser =
potentialUser |> Option.map userView |> Option.defaultValue userNotFoundView
let renderUserHandler userId =
fun next ctx ->
userId
|> queryUserById
|> Task.map renderUserOrNotFound
|> Task.bind (fun view -> htmlView view next ctx)
let handler: HttpHandler = routef "/users/%i" renderUserHandler
let webApplicationBuilder = WebApplication.CreateBuilder()
webApplicationBuilder.Services.AddGiraffe() |> ignore
let webApp = webApplicationBuilder.Build()
webApp.UseGiraffe handler
webApp.Run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment