packages feed

extism-pdk 0.2.0.0 → 1.0.0.0

raw patch · 11 files changed

+185/−56 lines, 11 filesdep ~extism-manifestPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: extism-manifest

API changes (from Hackage documentation)

- Extism.PDK: Debug :: LogLevel
- Extism.PDK: Error :: LogLevel
- Extism.PDK: Info :: LogLevel
- Extism.PDK: JSONValue :: a -> JSONValue a
- Extism.PDK: MsgPackValue :: a -> MsgPackValue a
- Extism.PDK: Warn :: LogLevel
- Extism.PDK: newtype JSONValue a
- Extism.PDK: newtype MsgPackValue a
- Extism.PDK.HTTP: type Request = HTTPRequest
- Extism.PDK.Memory: JSONValue :: a -> JSONValue a
- Extism.PDK.Memory: MsgPackValue :: a -> MsgPackValue a
- Extism.PDK.Memory: instance Extism.PDK.MsgPack.MsgPack a => Extism.PDK.Memory.FromBytes (Extism.PDK.Memory.MsgPackValue a)
- Extism.PDK.Memory: instance Extism.PDK.MsgPack.MsgPack a => Extism.PDK.Memory.ToBytes (Extism.PDK.Memory.MsgPackValue a)
- Extism.PDK.Memory: instance Text.JSON.JSON a => Extism.PDK.Memory.FromBytes (Extism.PDK.Memory.JSONValue a)
- Extism.PDK.Memory: instance Text.JSON.JSON a => Extism.PDK.Memory.ToBytes (Extism.PDK.Memory.JSONValue a)
- Extism.PDK.Memory: newtype JSONValue a
- Extism.PDK.Memory: newtype MsgPackValue a
+ Extism.PDK: JSON :: a -> JSON a
+ Extism.PDK: LogDebug :: LogLevel
+ Extism.PDK: LogError :: LogLevel
+ Extism.PDK: LogInfo :: LogLevel
+ Extism.PDK: LogWarn :: LogLevel
+ Extism.PDK: MsgPack :: a -> MsgPack a
+ Extism.PDK: logDebug :: String -> IO ()
+ Extism.PDK: logError :: String -> IO ()
+ Extism.PDK: logInfo :: String -> IO ()
+ Extism.PDK: logWarn :: String -> IO ()
+ Extism.PDK: newtype JSON a
+ Extism.PDK: newtype MsgPack a
+ Extism.PDK.Bindings: extismLengthUnsafe :: MemoryOffset -> IO MemoryLength
+ Extism.PDK.HTTP: Request :: String -> [(String, String)] -> String -> Request
+ Extism.PDK.HTTP: [headers] :: Request -> [(String, String)]
+ Extism.PDK.HTTP: [method] :: Request -> String
+ Extism.PDK.HTTP: [url] :: Request -> String
+ Extism.PDK.HTTP: data Request
+ Extism.PDK.HTTP: instance Data.Data.Data Extism.PDK.HTTP.Request
+ Extism.PDK.Memory: JSON :: a -> JSON a
+ Extism.PDK.Memory: MsgPack :: a -> MsgPack a
+ Extism.PDK.Memory: instance Data.Data.Data a => Extism.PDK.Memory.FromBytes (Extism.PDK.Memory.JSON a)
+ Extism.PDK.Memory: instance Data.Data.Data a => Extism.PDK.Memory.ToBytes (Extism.PDK.Memory.JSON a)
+ Extism.PDK.Memory: instance Extism.PDK.MsgPack.MsgPack a => Extism.PDK.Memory.FromBytes (Extism.PDK.Memory.MsgPack a)
+ Extism.PDK.Memory: instance Extism.PDK.MsgPack.MsgPack a => Extism.PDK.Memory.ToBytes (Extism.PDK.Memory.MsgPack a)
+ Extism.PDK.Memory: newtype JSON a
+ Extism.PDK.Memory: newtype MsgPack a
- Extism.PDK: inputJSON :: JSON a => IO (Either String a)
+ Extism.PDK: inputJSON :: Data a => IO a
- Extism.PDK: outputJSON :: JSON a => a -> IO ()
+ Extism.PDK: outputJSON :: Data a => a -> IO ()
- Extism.PDK.HTTP: responseJSON :: JSON a => Response -> IO (Either String a)
+ Extism.PDK.HTTP: responseJSON :: Data a => Response -> IO (Either String a)

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for extism-pdk +## 1.0.0.0++* Extism 1.0 compatible release+ ## 0.2.0.0  * API redesign, add automatic Haskell encoding using `ToMemory` and `FromMemory` classes
examples/CountVowels.hs view
@@ -1,8 +1,16 @@+{-# LANGUAGE DeriveDataTypeable #-}+ module CountVowels where  import Extism.PDK import Extism.PDK.JSON +data Output = Output+  { count :: Int+  }+  deriving+    (Data, Typeable)+ isVowel c =   c == 'a'     || c == 'A'@@ -21,6 +29,6 @@   -- Calculate the number of vowels   let count = length (filter isVowel s)   -- Return a JSON object {"count": count} back to the host-  output $ JSONValue $ object ["count" .= count]+  output $ JSON $ Output count  foreign export ccall "count_vowels" countVowels :: IO ()
examples/HTTPGet.hs view
@@ -8,7 +8,7 @@ getInput = do   req <- tryInput   case req of-    Right (JSONValue x) -> return x+    Right (JSON x) -> return x     Left e -> do       putStrLn e       url <- inputString
examples/Hello.hs view
@@ -1,8 +1,10 @@+{-# LANGUAGE DeriveDataTypeable #-}+ module Hello where  import Data.Maybe import Extism.PDK-import Foreign.C.Types+import Extism.PDK.JSON  defaultGreeting = "Hello" 
extism-pdk.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               extism-pdk-version:            0.2.0.0+version:            1.0.0.0  -- A short (one-line) description of the package. synopsis: Extism Plugin Development Kit@@ -39,13 +39,14 @@       bytestring >= 0.11.4 && <= 0.12,       cereal >= 0.5.8 && < 0.6,       containers >= 0.6.7 && < 0.7,-      extism-manifest >= 0.3.0 && <= 1.0.0,+      extism-manifest >= 1.0.0 && < 2.0.0,       json >= 0.11 && < 0.12,       messagepack >= 0.5.5 && < 0.6,       binary >= 0.8.9 && < 0.9.0      hs-source-dirs:   src     default-language: Haskell2010+    c-sources: src/extism-pdk.c  executable hello     scope: private
src/Extism/PDK.hs view
@@ -6,8 +6,8 @@   ( module Extism.PDK,     ToBytes (..),     FromBytes (..),-    JSONValue (..),-    MsgPackValue (..),+    JSON (..),+    MsgPack (..),   ) where @@ -16,7 +16,8 @@ import Extism.PDK.Memory import qualified Extism.PDK.MsgPack (MsgPack, decode, encode) import Extism.PDK.Util-import Text.JSON (JSON, decode, encode, resultToEither)+import qualified Text.JSON (decode, encode, resultToEither)+import qualified Text.JSON.Generic  -- | Get plugin input, returning an error message if the encoding is invalid tryInput :: (FromBytes a) => IO (Either String a)@@ -44,15 +45,9 @@   readInputBytes len  -- | Get input as 'JSON', this is similar to calling `input (JsonValue ...)`-inputJSON :: (JSON a) => IO (Either String a)+inputJSON :: (Text.JSON.Generic.Data a) => IO a inputJSON = do-  s <- tryInput :: IO (Either String String)-  case s of-    Left e -> return (Left e)-    Right x ->-      case resultToEither $ decode x of-        Left e -> return (Left e)-        Right y -> return (Right y)+  Text.JSON.Generic.decodeJSON <$> input  -- | Set plugin output output :: (ToBytes a) => a -> IO ()@@ -61,9 +56,9 @@   extismSetOutput offs len  -- | Set plugin output to a JSON encoded version of the provided value-outputJSON :: (JSON a) => a -> IO ()+outputJSON :: (Text.JSON.Generic.Data a) => a -> IO () outputJSON x =-  output (encode x)+  output (Text.JSON.Generic.encodeJSON x)  -- | Get a variable from the Extism runtime getVar :: (FromBytes a) => String -> IO (Maybe a)@@ -115,23 +110,39 @@   extismSetError $ memoryOffset s  -- | Log level-data LogLevel = Info | Debug | Warn | Error+data LogLevel = LogInfo | LogDebug | LogWarn | LogError  -- | Log to configured log file log :: LogLevel -> String -> IO ()-log Info msg = do+log LogInfo msg = do   s <- allocString msg   extismLogInfo (memoryOffset s)   free s-log Debug msg = do+log LogDebug msg = do   s <- allocString msg   extismLogDebug (memoryOffset s)   free s-log Warn msg = do+log LogWarn msg = do   s <- allocString msg   extismLogWarn (memoryOffset s)   free s-log Error msg = do+log LogError msg = do   s <- allocString msg   extismLogError (memoryOffset s)   free s++-- Log with "error" level+logError :: String -> IO ()+logError = Extism.PDK.log LogError++-- Log with "info" level+logInfo :: String -> IO ()+logInfo = Extism.PDK.log LogInfo++-- Log with "debug" level+logDebug :: String -> IO ()+logDebug = Extism.PDK.log LogDebug++-- Log with "warn" level+logWarn :: String -> IO ()+logWarn = Extism.PDK.log LogWarn
src/Extism/PDK/Bindings.hs view
@@ -49,6 +49,8 @@  foreign import ccall "extism_length" extismLength :: MemoryOffset -> IO MemoryLength +foreign import ccall "extism_length_unsafe" extismLengthUnsafe :: MemoryOffset -> IO MemoryLength+ foreign import ccall "extism_free" extismFree :: MemoryOffset -> IO ()  foreign import ccall "extism_input_length" extismInputLength :: IO InputLength
src/Extism/PDK/HTTP.hs view
@@ -1,17 +1,26 @@+{-# LANGUAGE DeriveDataTypeable #-}+ -- | -- Contains bindings to the Extism PDK HTTP interface module Extism.PDK.HTTP where  import Data.ByteString as B import Data.Word-import Extism.JSON (JSON, Nullable (..), Result (..), decode)-import Extism.Manifest (HTTPRequest (..), headers, method, toString, url)+import Extism.JSON (Nullable (..))+import qualified Extism.Manifest (HTTPRequest (..)) import Extism.PDK import Extism.PDK.Bindings import Extism.PDK.Memory+import Text.JSON (Result(..), decode, encode, makeObj)+import qualified Text.JSON.Generic  -- | HTTP Request-type Request = HTTPRequest+data Request = Request+  { url :: String,+    headers :: [(String, String)],+    method :: String+  }+  deriving (Text.JSON.Generic.Typeable, Text.JSON.Generic.Data)  -- | HTTP Response data Response = Response@@ -22,21 +31,17 @@ -- | Creates a new 'Request' newRequest :: String -> Request newRequest url =-  HTTPRequest-    { url = url,-      headers = Null,-      method = Null-    }+  Request url [] "GET"  -- | Update a 'Request' with the provided HTTP request method (GET, POST, PUT, DELETE, ...) withMethod :: String -> Request -> Request withMethod meth req =-  req {method = NotNull meth}+  req {method = meth}  -- | Update a 'Request' with the provided HTTP request headers withHeaders :: [(String, String)] -> Request -> Request withHeaders h req =-  req {headers = NotNull h}+  req {headers = h}  -- | Access the Memory block associated with a 'Response' responseMemory :: Response -> Memory@@ -55,12 +60,15 @@ responseString (Response _ mem) = loadString mem  -- | Get the 'Response' body as JSON-responseJSON :: (JSON a) => Response -> IO (Either String a)+responseJSON :: (Text.JSON.Generic.Data a) => Response -> IO (Either String a) responseJSON (Response _ mem) = do   json <- decode <$> loadString mem   case json of-    Ok json -> return $ Right json-    Extism.JSON.Error msg -> return (Left msg)+    Ok json ->+      case Text.JSON.Generic.fromJSON json of+        Ok x -> return $ Right x+        Error msg -> return (Left msg)+    Error msg -> return (Left msg)  -- | Get the 'Response' body and decode it response :: (FromBytes a) => Response -> IO (Either String a)@@ -70,7 +78,13 @@ sendRequestWithBody :: (ToBytes a) => Request -> a -> IO Response sendRequestWithBody req b = do   body <- alloc b-  let json = Extism.Manifest.toString req+  let json =+        encode+          Extism.Manifest.HTTPRequest+            { Extism.Manifest.url = url req,+              Extism.Manifest.headers = NotNull $ headers req,+              Extism.Manifest.method = NotNull $ method req+            }   j <- allocString json   res <- extismHTTPRequest (memoryOffset j) (memoryOffset body)   free j@@ -85,7 +99,13 @@ -- | Send HTTP request with an optional request body sendRequest :: (ToBytes a) => Request -> Maybe a -> IO Response sendRequest req b =-  let json = Extism.Manifest.toString req+  let json =+        encode+          Extism.Manifest.HTTPRequest+            { Extism.Manifest.url = url req,+              Extism.Manifest.headers = NotNull $ headers req,+              Extism.Manifest.method = NotNull $ method req+            }    in let bodyMem = case b of             Nothing -> return $ Memory 0 0             Just b -> alloc b@@ -99,5 +119,5 @@             if res == 0               then return (Response (fromIntegral code) (Memory 0 0))               else do-                mem <- findMemory res-                return (Response (fromIntegral code) mem)+                len <- extismLengthUnsafe res+                return (Response (fromIntegral code) (Memory res len))
src/Extism/PDK/JSON.hs view
@@ -1,7 +1,9 @@ module Extism.PDK.JSON   ( module Extism.PDK.JSON,     module Extism.JSON,+    module Text.JSON.Generic,   ) where -import Extism.JSON+import qualified Extism.JSON+import Text.JSON.Generic
src/Extism/PDK/Memory.hs view
@@ -8,8 +8,8 @@     MemoryLength,     FromBytes (..),     ToBytes (..),-    JSONValue (..),-    MsgPackValue (..),+    JSON (..),+    MsgPack (..),     load,     loadString,     loadByteString,@@ -34,7 +34,8 @@ import Extism.PDK.Bindings import qualified Extism.PDK.MsgPack (MsgPack, decode, encode) import Extism.PDK.Util-import Text.JSON (JSON, decode, encode, resultToEither)+import qualified Text.JSON (JSON, Result (..), decode, encode)+import qualified Text.JSON.Generic  -- | Represents a block of memory by offset and length data Memory = Memory MemoryOffset MemoryLength@@ -135,10 +136,10 @@   toBytes :: a -> B.ByteString  -- | A wrapper type for JSON encoded values-newtype JSONValue a = JSONValue a+newtype JSON a = JSON a  -- | A wrapper type for MsgPack encoded values-newtype MsgPackValue a = MsgPackValue a+newtype MsgPack a = MsgPack a  instance FromBytes B.ByteString where   fromBytes = Right@@ -156,20 +157,23 @@ instance ToBytes String where   toBytes = toByteString -instance (JSON a) => FromBytes (JSONValue a) where+instance (Text.JSON.Generic.Data a) => FromBytes (JSON a) where   fromBytes mem =     let a = fromBytes mem      in case a of           Left e -> Left e           Right x ->-            case resultToEither $ decode x of-              Left e -> Left e-              Right y -> Right (JSONValue y)+            case Text.JSON.decode x of+              Text.JSON.Error e -> Left e+              Text.JSON.Ok y ->+                case Text.JSON.Generic.fromJSON y of+                  Text.JSON.Error e -> Left e+                  Text.JSON.Ok z -> Right (JSON z) -instance (JSON a) => ToBytes (JSONValue a) where-  toBytes (JSONValue x) = toBytes (encode x)+instance (Text.JSON.Generic.Data a) => ToBytes (JSON a) where+  toBytes (JSON x) = toBytes (Text.JSON.Generic.encodeJSON x) -instance (Extism.PDK.MsgPack.MsgPack a) => FromBytes (MsgPackValue a) where+instance (Extism.PDK.MsgPack.MsgPack a) => FromBytes (MsgPack a) where   fromBytes mem =     let a = fromBytes mem      in case a of@@ -177,10 +181,10 @@           Right x ->             case Extism.PDK.MsgPack.decode x of               Left e -> Left e-              Right y -> Right (MsgPackValue y)+              Right y -> Right (MsgPack y) -instance (Extism.PDK.MsgPack.MsgPack a) => ToBytes (MsgPackValue a) where-  toBytes (MsgPackValue x) = toBytes $ Extism.PDK.MsgPack.encode x+instance (Extism.PDK.MsgPack.MsgPack a) => ToBytes (MsgPack a) where+  toBytes (MsgPack x) = toBytes $ Extism.PDK.MsgPack.encode x  instance ToBytes Int32 where   toBytes i = toBytes $ B.toStrict (runPut (putInt32le i))
+ src/extism-pdk.c view
@@ -0,0 +1,75 @@+#include <stdint.h>++#define IMPORT(a, b) __attribute__((import_module(a), import_name(b)))++typedef uint64_t ExtismPointer;++#define DEFINE(name, t, ...)                                                   \+  IMPORT("extism:host/env", #name) extern t _##name(__VA_ARGS__);++DEFINE(input_length, uint64_t)+uint64_t extism_input_length() { return _input_length(); }++DEFINE(length, uint64_t, ExtismPointer)+uint64_t extism_length(ExtismPointer p) { return _length(p); }++DEFINE(length_unsafe, uint64_t, ExtismPointer)+uint64_t extism_length_unsafe(ExtismPointer p) { return _length_unsafe(p); }++DEFINE(alloc, ExtismPointer, uint64_t)+uint64_t extism_alloc(uint64_t n) { return _alloc(n); }++DEFINE(free, void, ExtismPointer)+void extism_free(uint64_t n) { return _free(n); }++DEFINE(input_load_u8, uint8_t, ExtismPointer)+uint8_t extism_input_load_u8(ExtismPointer p) { return _input_load_u8(p); }++DEFINE(input_load_u64, uint64_t, ExtismPointer)+uint64_t extism_input_load_u64(ExtismPointer p) { return _input_load_u64(p); }++DEFINE(output_set, void, ExtismPointer, uint64_t)+void extism_output_set(ExtismPointer p, uint64_t n) {+  return _output_set(p, n);+}++DEFINE(error_set, void, ExtismPointer)+void extism_error_set(ExtismPointer p) { _error_set(p); }++DEFINE(config_get, ExtismPointer, ExtismPointer)+ExtismPointer extism_config_get(ExtismPointer p) { return _config_get(p); }++DEFINE(var_get, ExtismPointer, ExtismPointer)+ExtismPointer extism_var_get(ExtismPointer p) { return _var_get(p); }++DEFINE(var_set, void, ExtismPointer, ExtismPointer)+void extism_var_set(ExtismPointer k, ExtismPointer v) { return _var_set(k, v); }++DEFINE(store_u8, void, ExtismPointer, uint8_t)+void extism_store_u8(ExtismPointer p, uint8_t x) { return _store_u8(p, x); }++DEFINE(load_u8, uint8_t, ExtismPointer)+uint8_t extism_load_u8(ExtismPointer p) { return _load_u8(p); }++DEFINE(store_u64, void, ExtismPointer, uint64_t)+void extism_store_u64(ExtismPointer p, uint64_t x) { return _store_u64(p, x); }++DEFINE(load_u64, uint64_t, ExtismPointer)+uint64_t extism_load_u64(ExtismPointer p) { return _load_u64(p); }++DEFINE(http_request, ExtismPointer, ExtismPointer, ExtismPointer)+ExtismPointer extism_http_request(ExtismPointer req, ExtismPointer body) {+  return _http_request(req, body);+}++DEFINE(http_status_code, int32_t)+int32_t extism_http_status_code() { return _http_status_code(); }++DEFINE(log_info, void, ExtismPointer)+void extism_log_info(ExtismPointer p) { return _log_info(p); }+DEFINE(log_debug, void, ExtismPointer)+void extism_log_debug(ExtismPointer p) { return _log_debug(p); }+DEFINE(log_warn, void, ExtismPointer)+void extism_warn_info(ExtismPointer p) { return _log_warn(p); }+DEFINE(log_error, void, ExtismPointer)+void extism_log_error(ExtismPointer p) { return _log_error(p); }