Skip to content

Commit

Permalink
feat: Add support for alternative HTTP clients and move httpc to de…
Browse files Browse the repository at this point in the history
…v dependencies.
  • Loading branch information
vxern committed Jun 15, 2024
1 parent f358739 commit 2d20225
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 16 deletions.
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ gleam = ">= 1.2.0"
[dependencies]
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
gleam_http = ">= 3.6.0 and < 4.0.0"
gleam_httpc = ">= 2.2.0 and < 3.0.0"
gleam_json = ">= 1.0.0 and < 2.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
gleam_httpc = ">= 2.2.0 and < 3.0.0"
2 changes: 1 addition & 1 deletion manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ packages = [

[requirements]
gleam_http = { version = ">= 3.6.0 and < 4.0.0" }
gleam_httpc = { version = ">= 2.2.0 and < 3.0.0" }
gleam_httpc = { version = ">= 2.2.0 and < 3.0.0"}
gleam_json = { version = ">= 1.0.0 and < 2.0.0" }
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
11 changes: 8 additions & 3 deletions src/tatoeba/api.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import gleam/dynamic.{type Dynamic}
import gleam/http.{type Header}
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import gleam/json
import gleam/list
import gleam/option.{None, Some}
Expand All @@ -26,13 +26,18 @@ pub const headers: List(Header) = [

/// The possible errors API calls can fail with.
///
pub type ApiError {
pub type ApiError(error) {
/// Failed to make a request to Tatoeba.
RequestError(Dynamic)
RequestError(error)
/// Failed to decode the response data.
DecodeError(json.DecodeError)
}

/// Represents a function used to send a request to Tatoeba.
///
pub type RequestSender(error) =
fn(Request(String)) -> Result(Response(String), error)

/// Creates a new request to the given endpoint.
///
/// This function is used over the bare `request.from_uri()` to add a step
Expand Down
11 changes: 7 additions & 4 deletions src/tatoeba/search.gleam
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import gleam/dynamic.{type Dynamic, bool, field, int, list, optional, string}
import gleam/http
import gleam/http/request
import gleam/httpc
import gleam/json
import gleam/list
import gleam/option.{type Option, None, Some}
Expand Down Expand Up @@ -319,14 +318,18 @@ fn results(

/// Runs a search query using the passed `options` to filter the results.
///
pub fn run(options: SearchOptions) -> Result(SearchResults, api.ApiError) {
pub fn run(
options: SearchOptions,
using send_request: api.RequestSender(error),
) -> Result(SearchResults, api.ApiError(error)) {
let request =
api.new_request_to("/search")
|> request.set_method(http.Get)
|> request.set_query(to_query_parameters(options))

use response <- result.try(
httpc.send(request)
request
|> send_request()
|> result.map_error(fn(error) { api.RequestError(error) }),
)

Expand All @@ -335,7 +338,7 @@ pub fn run(options: SearchOptions) -> Result(SearchResults, api.ApiError) {

/// Decodes the received search payload.
///
fn decode_payload(payload: String) -> Result(SearchResults, api.ApiError) {
fn decode_payload(payload: String) -> Result(SearchResults, api.ApiError(error)) {
use results <- result.try(
json.decode(payload, results)
|> result.map_error(fn(error) { api.DecodeError(error) }),
Expand Down
11 changes: 7 additions & 4 deletions src/tatoeba/sentence.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import gleam/dynamic.{
}
import gleam/http
import gleam/http/request
import gleam/httpc
import gleam/int
import gleam/json
import gleam/option.{type Option, None, Some}
Expand Down Expand Up @@ -564,13 +563,17 @@ pub fn new_id(id: Int) -> Result(SentenceId, IdError) {

/// Gets data of a single sentence in the Tatoeba corpus.
///
pub fn get(id id: SentenceId) -> Result(Option(Sentence), api.ApiError) {
pub fn get(
id id: SentenceId,
using send_request: api.RequestSender(error),
) -> Result(Option(Sentence), api.ApiError(error)) {
let request =
api.new_request_to("/sentence/" <> int.to_string(id.value))
|> request.set_method(http.Get)

use response <- result.try(
httpc.send(request)
request
|> send_request()
|> result.map_error(fn(error) { api.RequestError(error) }),
)

Expand All @@ -582,7 +585,7 @@ pub fn get(id id: SentenceId) -> Result(Option(Sentence), api.ApiError) {

/// Decodes the received sentence payload.
///
fn decode_payload(payload: String) -> Result(Sentence, api.ApiError) {
fn decode_payload(payload: String) -> Result(Sentence, api.ApiError(error)) {
use sentence <- result.try(
json.decode(payload, sentence)
|> result.map_error(fn(error) { api.DecodeError(error) }),
Expand Down
7 changes: 4 additions & 3 deletions test/sentence_test.gleam
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import gleam/httpc
import gleam/list
import gleam/option.{None, Some}
import gleeunit/should
Expand All @@ -18,7 +19,7 @@ pub fn new_id_test() {

pub fn sentence_exists_test() {
let assert Ok(id) = sentence.new_id(12_212_258)
let result = sentence.get(id)
let result = sentence.get(id, using: httpc.send)

result |> should.be_ok()

Expand All @@ -37,7 +38,7 @@ pub fn failed_decoding_test() {

pub fn sentence_removed_test() {
let assert Ok(id) = sentence.new_id(4_802_955)
let result = sentence.get(id)
let result = sentence.get(id, using: httpc.send)

result |> should.be_ok()

Expand All @@ -48,7 +49,7 @@ pub fn sentence_removed_test() {

pub fn sentence_get_test() {
let assert Ok(id) = sentence.new_id(1)
let assert Ok(Some(sentence)) = sentence.get(id)
let assert Ok(Some(sentence)) = sentence.get(id, using: httpc.send)

sentence.id |> should.equal(1)
sentence.text |> should.equal("我們試試看!")
Expand Down

0 comments on commit 2d20225

Please sign in to comment.