1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-11-23 22:14:53 +02:00

fix: some minor improvements

Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
Dr. Carsten Leue
2025-11-13 12:56:51 +01:00
parent 3c3bb7c166
commit b70e481e7d
3 changed files with 48 additions and 35 deletions

View File

@@ -53,12 +53,12 @@ import (
RIOE "github.com/IBM/fp-go/v2/context/readerioresult" RIOE "github.com/IBM/fp-go/v2/context/readerioresult"
RIOEH "github.com/IBM/fp-go/v2/context/readerioresult/http" RIOEH "github.com/IBM/fp-go/v2/context/readerioresult/http"
E "github.com/IBM/fp-go/v2/either"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
R "github.com/IBM/fp-go/v2/http/builder" R "github.com/IBM/fp-go/v2/http/builder"
H "github.com/IBM/fp-go/v2/http/headers" H "github.com/IBM/fp-go/v2/http/headers"
LZ "github.com/IBM/fp-go/v2/lazy" LZ "github.com/IBM/fp-go/v2/lazy"
O "github.com/IBM/fp-go/v2/option" O "github.com/IBM/fp-go/v2/option"
"github.com/IBM/fp-go/v2/result"
) )
// Requester converts an http/builder.Builder into a ReaderIOResult that produces HTTP requests. // Requester converts an http/builder.Builder into a ReaderIOResult that produces HTTP requests.
@@ -143,10 +143,10 @@ func Requester(builder *R.Builder) RIOEH.Requester {
return F.Pipe5( return F.Pipe5(
builder.GetBody(), builder.GetBody(),
O.Fold(LZ.Of(E.Of[error](withoutBody)), E.Map[error](withBody)), O.Fold(LZ.Of(result.Of(withoutBody)), result.Map(withBody)),
E.Ap[func(string) RIOE.ReaderIOResult[*http.Request]](builder.GetTargetURL()), result.Ap[RIOE.Kleisli[string, *http.Request]](builder.GetTargetURL()),
E.Flap[error, RIOE.ReaderIOResult[*http.Request]](builder.GetMethod()), result.Flap[RIOE.ReaderIOResult[*http.Request]](builder.GetMethod()),
E.GetOrElse(RIOE.Left[*http.Request]), result.GetOrElse(RIOE.Left[*http.Request]),
RIOE.Map(func(req *http.Request) *http.Request { RIOE.Map(func(req *http.Request) *http.Request {
req.Header = H.Monoid.Concat(req.Header, builder.GetHeaders()) req.Header = H.Monoid.Concat(req.Header, builder.GetHeaders())
return req return req

View File

@@ -80,7 +80,6 @@ import (
A "github.com/IBM/fp-go/v2/array" A "github.com/IBM/fp-go/v2/array"
B "github.com/IBM/fp-go/v2/bytes" B "github.com/IBM/fp-go/v2/bytes"
E "github.com/IBM/fp-go/v2/either"
ENDO "github.com/IBM/fp-go/v2/endomorphism" ENDO "github.com/IBM/fp-go/v2/endomorphism"
F "github.com/IBM/fp-go/v2/function" F "github.com/IBM/fp-go/v2/function"
C "github.com/IBM/fp-go/v2/http/content" C "github.com/IBM/fp-go/v2/http/content"
@@ -91,16 +90,17 @@ import (
L "github.com/IBM/fp-go/v2/optics/lens" L "github.com/IBM/fp-go/v2/optics/lens"
O "github.com/IBM/fp-go/v2/option" O "github.com/IBM/fp-go/v2/option"
R "github.com/IBM/fp-go/v2/record" R "github.com/IBM/fp-go/v2/record"
"github.com/IBM/fp-go/v2/result"
S "github.com/IBM/fp-go/v2/string" S "github.com/IBM/fp-go/v2/string"
T "github.com/IBM/fp-go/v2/tuple" T "github.com/IBM/fp-go/v2/tuple"
) )
type ( type (
Builder struct { Builder struct {
method O.Option[string] method Option[string]
url string url string
headers http.Header headers http.Header
body O.Option[E.Either[error, []byte]] body Option[Result[[]byte]]
query url.Values query url.Values
} }
@@ -117,19 +117,19 @@ var (
// Monoid is the [M.Monoid] for the [Endomorphism] // Monoid is the [M.Monoid] for the [Endomorphism]
Monoid = ENDO.Monoid[*Builder]() Monoid = ENDO.Monoid[*Builder]()
// Url is a [L.Lens] for the URL // Url is a [Lens] for the URL
// //
// Deprecated: use [URL] instead // Deprecated: use [URL] instead
Url = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL) Url = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL)
// URL is a [L.Lens] for the URL // URL is a [Lens] for the URL
URL = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL) URL = L.MakeLensRef((*Builder).GetURL, (*Builder).SetURL)
// Method is a [L.Lens] for the HTTP method // Method is a [Lens] for the HTTP method
Method = L.MakeLensRef((*Builder).GetMethod, (*Builder).SetMethod) Method = L.MakeLensRef((*Builder).GetMethod, (*Builder).SetMethod)
// Body is a [L.Lens] for the request body // Body is a [Lens] for the request body
Body = L.MakeLensRef((*Builder).GetBody, (*Builder).SetBody) Body = L.MakeLensRef((*Builder).GetBody, (*Builder).SetBody)
// Headers is a [L.Lens] for the complete set of request headers // Headers is a [Lens] for the complete set of request headers
Headers = L.MakeLensRef((*Builder).GetHeaders, (*Builder).SetHeaders) Headers = L.MakeLensRef((*Builder).GetHeaders, (*Builder).SetHeaders)
// Query is a [L.Lens] for the set of query parameters // Query is a [Lens] for the set of query parameters
Query = L.MakeLensRef((*Builder).GetQuery, (*Builder).SetQuery) Query = L.MakeLensRef((*Builder).GetQuery, (*Builder).SetQuery)
rawQuery = L.MakeLensRef(getRawQuery, setRawQuery) rawQuery = L.MakeLensRef(getRawQuery, setRawQuery)
@@ -139,11 +139,11 @@ var (
setHeader = F.Bind2of3((*Builder).SetHeader) setHeader = F.Bind2of3((*Builder).SetHeader)
noHeader = O.None[string]() noHeader = O.None[string]()
noBody = O.None[E.Either[error, []byte]]() noBody = O.None[Result[[]byte]]()
noQueryArg = O.None[string]() noQueryArg = O.None[string]()
parseURL = E.Eitherize1(url.Parse) parseURL = result.Eitherize1(url.Parse)
parseQuery = E.Eitherize1(url.ParseQuery) parseQuery = result.Eitherize1(url.ParseQuery)
// WithQuery creates a [Endomorphism] for a complete set of query parameters // WithQuery creates a [Endomorphism] for a complete set of query parameters
WithQuery = Query.Set WithQuery = Query.Set
@@ -159,12 +159,12 @@ var (
WithHeaders = Headers.Set WithHeaders = Headers.Set
// WithBody creates a [Endomorphism] for a request body // WithBody creates a [Endomorphism] for a request body
WithBody = F.Flow2( WithBody = F.Flow2(
O.Of[E.Either[error, []byte]], O.Of[Result[[]byte]],
Body.Set, Body.Set,
) )
// WithBytes creates a [Endomorphism] for a request body using bytes // WithBytes creates a [Endomorphism] for a request body using bytes
WithBytes = F.Flow2( WithBytes = F.Flow2(
E.Of[error, []byte], result.Of[[]byte],
WithBody, WithBody,
) )
// WithContentType adds the [H.ContentType] header // WithContentType adds the [H.ContentType] header
@@ -202,7 +202,7 @@ var (
) )
// bodyAsBytes returns a []byte with a fallback to the empty array // bodyAsBytes returns a []byte with a fallback to the empty array
bodyAsBytes = O.Fold(B.Empty, E.Fold(F.Ignore1of1[error](B.Empty), F.Identity[[]byte])) bodyAsBytes = O.Fold(B.Empty, result.Fold(F.Ignore1of1[error](B.Empty), F.Identity[[]byte]))
) )
func setRawQuery(u *url.URL, raw string) *url.URL { func setRawQuery(u *url.URL, raw string) *url.URL {
@@ -223,35 +223,35 @@ func (builder *Builder) clone() *Builder {
// GetTargetUrl constructs a full URL with query parameters on top of the provided URL string // GetTargetUrl constructs a full URL with query parameters on top of the provided URL string
// //
// Deprecated: use [GetTargetURL] instead // Deprecated: use [GetTargetURL] instead
func (builder *Builder) GetTargetUrl() E.Either[error, string] { func (builder *Builder) GetTargetUrl() Result[string] {
return builder.GetTargetURL() return builder.GetTargetURL()
} }
// GetTargetURL constructs a full URL with query parameters on top of the provided URL string // GetTargetURL constructs a full URL with query parameters on top of the provided URL string
func (builder *Builder) GetTargetURL() E.Either[error, string] { func (builder *Builder) GetTargetURL() Result[string] {
// construct the final URL // construct the final URL
return F.Pipe3( return F.Pipe3(
builder, builder,
Url.Get, Url.Get,
parseURL, parseURL,
E.Chain(F.Flow4( result.Chain(F.Flow4(
T.Replicate2[*url.URL], T.Replicate2[*url.URL],
T.Map2( T.Map2(
F.Flow2( F.Flow2(
F.Curry2(setRawQuery), F.Curry2(setRawQuery),
E.Of[error, func(string) *url.URL], result.Of[func(string) *url.URL],
), ),
F.Flow3( F.Flow3(
rawQuery.Get, rawQuery.Get,
parseQuery, parseQuery,
E.Map[error](F.Flow2( result.Map(F.Flow2(
F.Curry2(FM.ValuesMonoid.Concat)(builder.GetQuery()), F.Curry2(FM.ValuesMonoid.Concat)(builder.GetQuery()),
(url.Values).Encode, (url.Values).Encode,
)), )),
), ),
), ),
T.Tupled2(E.MonadAp[*url.URL, error, string]), T.Tupled2(result.MonadAp[*url.URL, string]),
E.Map[error]((*url.URL).String), result.Map((*url.URL).String),
)), )),
) )
} }
@@ -285,7 +285,7 @@ func (builder *Builder) SetQuery(query url.Values) *Builder {
return builder return builder
} }
func (builder *Builder) GetBody() O.Option[E.Either[error, []byte]] { func (builder *Builder) GetBody() Option[Result[[]byte]] {
return builder.body return builder.body
} }
@@ -310,7 +310,7 @@ func (builder *Builder) SetHeaders(headers http.Header) *Builder {
return builder return builder
} }
func (builder *Builder) SetBody(body O.Option[E.Either[error, []byte]]) *Builder { func (builder *Builder) SetBody(body Option[Result[[]byte]]) *Builder {
builder.body = body builder.body = body
return builder return builder
} }
@@ -325,7 +325,7 @@ func (builder *Builder) DelHeader(name string) *Builder {
return builder return builder
} }
func (builder *Builder) GetHeader(name string) O.Option[string] { func (builder *Builder) GetHeader(name string) Option[string] {
return F.Pipe2( return F.Pipe2(
name, name,
builder.headers.Get, builder.headers.Get,
@@ -342,8 +342,8 @@ func (builder *Builder) GetHash() string {
return MakeHash(builder) return MakeHash(builder)
} }
// Header returns a [L.Lens] for a single header // Header returns a [Lens] for a single header
func Header(name string) L.Lens[*Builder, O.Option[string]] { func Header(name string) Lens[*Builder, Option[string]] {
get := getHeader(name) get := getHeader(name)
set := F.Bind1of2(setHeader(name)) set := F.Bind1of2(setHeader(name))
del := F.Flow2( del := F.Flow2(
@@ -351,7 +351,7 @@ func Header(name string) L.Lens[*Builder, O.Option[string]] {
LZ.Map(delHeader(name)), LZ.Map(delHeader(name)),
) )
return L.MakeLens(get, func(b *Builder, value O.Option[string]) *Builder { return L.MakeLens(get, func(b *Builder, value Option[string]) *Builder {
cpy := b.clone() cpy := b.clone()
return F.Pipe1( return F.Pipe1(
value, value,
@@ -392,8 +392,8 @@ func WithJSON[T any](data T) Endomorphism {
) )
} }
// QueryArg is a [L.Lens] for the first value of a query argument // QueryArg is a [Lens] for the first value of a query argument
func QueryArg(name string) L.Lens[*Builder, O.Option[string]] { func QueryArg(name string) Lens[*Builder, Option[string]] {
return F.Pipe1( return F.Pipe1(
Query, Query,
L.Compose[*Builder](FM.AtValue(name)), L.Compose[*Builder](FM.AtValue(name)),

13
v2/http/builder/type.go Normal file
View File

@@ -0,0 +1,13 @@
package builder
import (
"github.com/IBM/fp-go/v2/optics/lens"
"github.com/IBM/fp-go/v2/option"
"github.com/IBM/fp-go/v2/result"
)
type (
Option[T any] = option.Option[T]
Result[T any] = result.Result[T]
Lens[S, T any] = lens.Lens[S, T]
)