aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/control/concurrency/frp.lux8
-rw-r--r--stdlib/source/lux/world/net/http/client.lux86
2 files changed, 90 insertions, 4 deletions
diff --git a/stdlib/source/lux/control/concurrency/frp.lux b/stdlib/source/lux/control/concurrency/frp.lux
index 52c59f7a4..0dae2798e 100644
--- a/stdlib/source/lux/control/concurrency/frp.lux
+++ b/stdlib/source/lux/control/concurrency/frp.lux
@@ -1,5 +1,5 @@
(.module:
- [lux (#- Source)
+ [lux #*
["." io (#+ IO io)]
[control
[predicate (#+ Predicate)]
@@ -25,7 +25,7 @@
(exception: #export channel-is-already-closed)
-(signature: #export (Source a)
+(signature: #export (Sink a)
(: (IO (Error Any))
close)
(: (-> a (IO (Error Any)))
@@ -34,7 +34,7 @@
(def: (source resolve)
(All [a]
(-> (promise.Resolver (Maybe [a (Channel a)]))
- (Source a)))
+ (Sink a)))
(let [source (atom.atom resolve)]
(structure
(def: close
@@ -80,7 +80,7 @@
(recur []))))))))))
(def: #export (channel _)
- (All [a] (-> Any [(Channel a) (Source a)]))
+ (All [a] (-> Any [(Channel a) (Sink a)]))
(let [[promise resolve] (promise.promise [])]
[promise (..source resolve)]))
diff --git a/stdlib/source/lux/world/net/http/client.lux b/stdlib/source/lux/world/net/http/client.lux
new file mode 100644
index 000000000..318a17ef6
--- /dev/null
+++ b/stdlib/source/lux/world/net/http/client.lux
@@ -0,0 +1,86 @@
+(.module:
+ [lux #*
+ [control
+ ["." monad (#+ do)]
+ [concurrency
+ ["." promise]
+ ["." frp (#+ Channel Sink)]]]
+ [data
+ ["." error]
+ [format
+ ["." context]]
+ [collection
+ ["." dictionary]]]
+ [platform
+ [compiler
+ ["." host]]]
+ ["." io (#+ IO)]
+ [host (#+ import:)]]
+ ["." // (#+ Data Client)
+ [// (#+ URL)]])
+
+(`` (for {(~~ (static host.jvm))
+ (as-is (import: #long java/lang/String)
+
+ (import: #long java/io/Flushable
+ (flush [] #io #try void))
+
+ (import: #long java/lang/AutoCloseable
+ (close [] #io #try void))
+
+ (import: #long java/io/OutputStream
+ (write [(Array byte)] #io #try void))
+
+ (import: #long java/net/URLConnection
+ (setRequestProperty [java/lang/String java/lang/String] #io #try void)
+ (setDoOutput [boolean] #io #try void)
+ (getOutputStream [] #io #try java/io/OutputStream)
+ (connect [] #io #try void))
+
+ (import: #long java/net/HttpURLConnection
+ (setRequestMethod [java/lang/String] #io #try void)
+ (disconnect [] #io #try void)
+ (getResponseCode [] #io #try int))
+
+ (import: #long java/net/URL
+ (new [java/lang/String])
+ (openConnection [] #io #try java/net/URLConnection)))}
+ ))
+
+(def: #export (request [method url headers body])
+ Client
+ (`` (for {(~~ (static host.jvm))
+ (promise.future
+ (do (error.with-error io.monad)
+ [conn (java/net/URL::openConnection (java/net/URL::new url))
+ #let [conn (:coerce java/net/HttpURLConnection conn)]
+ _ (java/net/HttpURLConnection::setRequestMethod (case method
+ #//.Post "POST"
+ #//.Get "GET"
+ #//.Put "PUT"
+ #//.Patch "PATCH"
+ #//.Delete "DELETE"
+ #//.Head "HEAD"
+ #//.Connect "CONNECT"
+ #//.Options "OPTIONS"
+ #//.Trace "TRACE")
+ conn)
+ _ (|> headers
+ dictionary.entries
+ (monad.map @ (function (_ [name value])
+ (java/net/URLConnection::setRequestProperty name value conn))))
+ _ (java/net/URLConnection::setDoOutput true conn)
+ sink (java/net/URLConnection::getOutputStream conn)
+ _ (java/io/OutputStream::write body sink)
+ _ (java/io/Flushable::flush sink)
+ _ (java/lang/AutoCloseable::close sink)
+ _ (java/net/URLConnection::connect conn)
+ status (java/net/HttpURLConnection::getResponseCode conn)
+ #let [[channel source] (: [(Channel Data) (Sink Data)]
+ (frp.channel []))]
+ _ (:: source close)
+ _ (java/net/HttpURLConnection::disconnect conn)]
+ (wrap [(.nat status)
+ {#//.headers context.empty
+ #//.body channel}])))}
+ )))