dd90e460创建于 2025年5月14日历史提交
import gleam/dict.{type Dict}
import gleam/dynamic/decode
import gleam/json
import gleam/list
import gleam/result
import simplifile
import youid/uuid

pub opaque type Connection {
  Connection(root: String)
}

pub fn connect(root: String) -> Connection {
  let assert Ok(_) = simplifile.create_directory_all(root)
  Connection(root)
}

pub fn disconnect(_connection: Connection) -> Nil {
  // Here we do nothing, but a real database would close the connection or do
  // some other teardown.
  Nil
}

pub fn with_connection(root: String, f: fn(Connection) -> t) -> t {
  let connection = connect(root)
  let result = f(connection)
  let _ = disconnect(connection)
  result
}

pub fn truncate(connection: Connection) -> Result(Nil, Nil) {
  let assert Ok(_) = simplifile.delete(connection.root)
  Ok(Nil)
}

pub fn list(connection: Connection) -> Result(List(String), Nil) {
  let assert Ok(_) = simplifile.create_directory_all(connection.root)
  simplifile.read_directory(connection.root)
  |> result.replace_error(Nil)
}

pub fn insert(
  connection: Connection,
  values: Dict(String, String),
) -> Result(String, Nil) {
  let assert Ok(_) = simplifile.create_directory_all(connection.root)
  let id = uuid.v4_string()
  let values =
    values
    |> dict.to_list
    |> list.map(fn(pair) { #(pair.0, json.string(pair.1)) })
  let json = json.to_string(json.object(values))
  use _ <- result.try(
    simplifile.write(file_path(connection, id), json)
    |> result.replace_error(Nil),
  )
  Ok(id)
}

pub fn read(
  connection: Connection,
  id: String,
) -> Result(Dict(String, String), Nil) {
  use data <- result.try(
    simplifile.read(file_path(connection, id))
    |> result.replace_error(Nil),
  )

  let decoder = decode.dict(decode.string, decode.string)

  use data <- result.try(
    json.parse(data, decoder)
    |> result.replace_error(Nil),
  )

  Ok(data)
}

fn file_path(connection: Connection, id: String) -> String {
  connection.root <> "/" <> id
}