extism-pdk 1.1.0.0 → 1.2.0.0
raw patch · 8 files changed
+155/−126 lines, 8 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Extism.PDK: LogTrace :: LogLevel
+ Extism.PDK: instance GHC.Enum.Enum Extism.PDK.LogLevel
+ Extism.PDK: logTrace :: String -> IO ()
+ Extism.PDK.Bindings: extismGetLogLevel :: IO Int32
+ Extism.PDK.Bindings: extismHTTPHeaders :: IO MemoryOffset
+ Extism.PDK.Bindings: extismLogTrace :: MemoryOffset -> IO ()
+ Extism.PDK.HTTP: [responseHeaders] :: Response -> [(String, String)]
+ Extism.PDK.HTTP: getHeaders :: IO [(String, String)]
- Extism.PDK.HTTP: Response :: Int -> ByteString -> Response
+ Extism.PDK.HTTP: Response :: Int -> ByteString -> [(String, String)] -> Response
Files
- CHANGELOG.md +5/−0
- examples/CountVowels.hs +4/−0
- extism-pdk.cabal +1/−1
- src/Extism/PDK.hs +19/−15
- src/Extism/PDK/Bindings.hs +8/−4
- src/Extism/PDK/HTTP.hs +46/−30
- src/Extism/PDK/Memory.hs +65/−76
- src/extism-pdk.c +7/−0
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for extism-pdk +## 1.2.0.0++* Add bindings to `http_headers` Extism host funtion+* Add `trace` level logging+ ## 1.1.0.0 * Remove calls to free where Extism host expects to take ownership
examples/CountVowels.hs view
@@ -22,6 +22,10 @@ countVowels = do -- Get input string from Extism host s <- input++ -- Log input+ () <- Extism.PDK.log LogInfo ("Got input: " ++ s)+ -- Calculate the number of vowels let count = length (filter isVowel s) -- Return a JSON object {"count": count} back to the host
extism-pdk.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: extism-pdk-version: 1.1.0.0+version: 1.2.0.0 -- A short (one-line) description of the package. synopsis: Extism Plugin Development Kit
src/Extism/PDK.hs view
@@ -27,8 +27,7 @@ input :: forall a. (FromBytes a) => IO a input = do i <- inputByteString- let x = fromBytes i- case x of+ case fromBytes i of Left e -> error e Right y -> return y @@ -104,22 +103,23 @@ extismSetError $ memoryOffset s -- | Log level-data LogLevel = LogInfo | LogDebug | LogWarn | LogError+data LogLevel = LogTrace | LogDebug | LogInfo | LogWarn | LogError deriving (Enum) -- | Log to configured log file log :: LogLevel -> String -> IO ()-log LogInfo msg = do- s <- allocString msg- extismLogInfo (memoryOffset s)-log LogDebug msg = do- s <- allocString msg- extismLogDebug (memoryOffset s)-log LogWarn msg = do- s <- allocString msg- extismLogWarn (memoryOffset s)-log LogError msg = do- s <- allocString msg- extismLogError (memoryOffset s)+log level msg = do+ configuredLevel <- extismGetLogLevel+ if fromIntegral (fromEnum level) < configuredLevel+ then return ()+ else do+ s <- allocString msg+ let offs = memoryOffset s+ case level of+ LogTrace -> extismLogTrace offs+ LogDebug -> extismLogDebug offs+ LogInfo -> extismLogInfo offs+ LogWarn -> extismLogWarn offs+ LogError -> extismLogError offs -- Log with "error" level logError :: String -> IO ()@@ -136,3 +136,7 @@ -- Log with "warn" level logWarn :: String -> IO () logWarn = Extism.PDK.log LogWarn++-- Log with "trace" level+logTrace :: String -> IO ()+logTrace = Extism.PDK.log LogTrace
src/Extism/PDK/Bindings.hs view
@@ -37,6 +37,10 @@ foreign import ccall "extism_log_error" extismLogError :: MemoryOffset -> IO () +foreign import ccall "extism_log_trace" extismLogTrace :: MemoryOffset -> IO ()++foreign import ccall "extism_get_log_level" extismGetLogLevel :: IO Int32+ foreign import ccall "extism_store_u8" extismStoreU8 :: MemoryOffset -> Word8 -> IO () foreign import ccall "extism_store_u64" extismStoreU64 :: MemoryOffset -> Word64 -> IO ()@@ -69,6 +73,8 @@ foreign import ccall "extism_http_status_code" extismHTTPStatusCode :: IO Int32 +foreign import ccall "extism_http_headers" extismHTTPHeaders :: IO MemoryOffset+ foreign import ccall "__wasm_call_ctors" wasmConstructor :: IO () foreign import ccall "__wasm_call_dtors" wasmDestructor :: IO ()@@ -90,9 +96,8 @@ if index >= total then return $ B.concat . Prelude.reverse $ acc else do- let diff = total - index (n, x) <-- if diff >= 8+ if total - index >= 8 then do u <- f8 index return (8, word64ToBS u)@@ -114,9 +119,8 @@ if index >= total then pure () else do- let diff = total - index (n, sub) <-- if diff >= 8+ if total - index >= 8 then do let (curr, next) = B.splitAt 8 src u <- bsToWord64 curr
src/Extism/PDK/HTTP.hs view
@@ -26,7 +26,8 @@ -- | HTTP Response data Response = Response { statusCode :: Int,- responseData :: ByteString+ responseData :: ByteString,+ responseHeaders :: [(String, String)] } -- | Creates a new 'Request'@@ -46,11 +47,11 @@ -- | Get the 'Response' body as a 'ByteString' responseByteString :: Response -> ByteString-responseByteString (Response _ mem) = mem+responseByteString (Response _ mem _) = mem -- | Get the 'Response' body as a 'String' responseString :: Response -> String-responseString (Response _ mem) = fromByteString mem+responseString (Response _ mem _) = fromByteString mem -- | Get the 'Response' body as JSON responseJSON :: (Text.JSON.Generic.Data a) => Response -> IO (Either String a)@@ -67,8 +68,21 @@ -- | Get the 'Response' body and decode it response :: (FromBytes a) => Response -> Either String a-response (Response _ mem) = fromBytes mem+response (Response _ mem _) = fromBytes mem +getHeaders = do+ offs <- extismHTTPHeaders+ if offs == 0+ then+ return []+ else do+ mem <- Extism.PDK.Memory.findMemory offs+ h <- Extism.PDK.Memory.load mem+ () <- Extism.PDK.Memory.free mem+ case h of+ Left _ -> return []+ Right (JSON x) -> return x+ -- | Send HTTP request with an optional request body sendRequestWithBody :: (ToBytes a) => Request -> a -> IO Response sendRequestWithBody req b = do@@ -83,37 +97,39 @@ j <- allocString json res <- extismHTTPRequest (memoryOffset j) (memoryOffset body) code <- extismHTTPStatusCode+ h <- getHeaders if res == 0- then return (Response (fromIntegral code) empty)+ then return (Response (fromIntegral code) empty h) else do mem <- findMemory res bs <- loadByteString mem free mem- return (Response (fromIntegral code) bs)+ return (Response (fromIntegral code) bs h) -- | Send HTTP request with an optional request body sendRequest :: (ToBytes a) => Request -> Maybe a -> IO Response-sendRequest req b =- 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- in do- body <- bodyMem- j <- allocString json- res <- extismHTTPRequest (memoryOffset j) (memoryOffset body)- code <- extismHTTPStatusCode- if res == 0- then return (Response (fromIntegral code) empty)- else do- len <- extismLengthUnsafe res- let mem = Memory res len- bs <- loadByteString mem- free mem- return (Response (fromIntegral code) bs)+sendRequest req b = do+ body <- bodyMem+ j <- allocString json+ res <- extismHTTPRequest (memoryOffset j) (memoryOffset body)+ code <- extismHTTPStatusCode+ h <- getHeaders+ if res == 0+ then return (Response (fromIntegral code) empty h)+ else do+ len <- extismLengthUnsafe res+ let mem = Memory res len+ bs <- loadByteString mem+ free mem+ return (Response (fromIntegral code) bs h)+ where+ json =+ encode+ Extism.Manifest.HTTPRequest+ { Extism.Manifest.url = url req,+ Extism.Manifest.headers = NotNull $ headers req,+ Extism.Manifest.method = NotNull $ method req+ }+ bodyMem = case b of+ Nothing -> return $ Memory 0 0+ Just b -> alloc b
src/Extism/PDK/Memory.hs view
@@ -49,8 +49,7 @@ -- | Store data into a 'Memory' block store :: (ToBytes a) => Memory -> a -> IO () store (Memory offs len) a =- let bs = toBytes a- in writeBytes offs len bs+ writeBytes offs len $ toBytes a -- | Set plugin output to the provided 'Memory' block outputMemory :: Memory -> IO ()@@ -70,8 +69,7 @@ -- | Store string in 'Memory' block storeString :: Memory -> String -> IO () storeString mem s =- let bs = toByteString s- in storeByteString mem bs+ storeByteString mem $ toByteString s -- | Store byte string in 'Memory' block storeByteString :: Memory -> B.ByteString -> IO ()@@ -80,20 +78,20 @@ -- | Encode a value and copy it into Extism memory, returning the Memory block alloc :: (ToBytes a) => a -> IO Memory-alloc x =- let bs = toBytes x- in do- Memory offs len <- memAlloc (B.length bs)- writeBytes offs len bs- return $ Memory offs len+alloc x = do+ Memory offs len <- memAlloc (B.length bs)+ writeBytes offs len bs+ return $ Memory offs len+ where+ bs = toBytes x -- | Allocate a new 'Memory' block memAlloc :: Int -> IO Memory-memAlloc n =- let len = fromIntegral n- in do- offs <- extismAlloc len- return $ Memory offs len+memAlloc n = do+ offs <- extismAlloc len+ return $ Memory offs len+ where+ len = fromIntegral n -- | Free a 'Memory' block free :: Memory -> IO ()@@ -149,39 +147,36 @@ instance FromBytes String where fromBytes mem =- let s = fromBytes mem- in case s of- Left e -> Left e- Right x -> Right $ fromByteString x+ case fromBytes mem of+ Left e -> Left e+ Right x -> Right $ fromByteString x instance ToBytes String where toBytes = toByteString 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 Text.JSON.decode x of+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ 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 y ->- case Text.JSON.Generic.fromJSON y of- Text.JSON.Error e -> Left e- Text.JSON.Ok z -> Right (JSON z)+ Text.JSON.Ok z -> Right (JSON z) 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 (MsgPack a) where fromBytes mem =- let a = fromBytes mem- in case a of+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case Extism.PDK.MsgPack.decode x of Left e -> Left e- Right x ->- case Extism.PDK.MsgPack.decode x of- Left e -> Left e- Right y -> Right (MsgPack y)+ Right y -> Right (MsgPack y) instance (Extism.PDK.MsgPack.MsgPack a) => ToBytes (MsgPack a) where toBytes (MsgPack x) = toBytes $ Extism.PDK.MsgPack.encode x@@ -191,75 +186,69 @@ instance FromBytes Int32 where fromBytes mem =- let bs = fromBytes mem- in case bs of- Left e -> Left e- Right x ->- case runGetOrFail getInt32le (B.fromStrict x) of- Left (_, _, e) -> Left e- Right (_, _, x) -> Right x+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case runGetOrFail getInt32le (B.fromStrict x) of+ Left (_, _, e) -> Left e+ Right (_, _, x) -> Right x instance ToBytes Int64 where toBytes i = toBytes $ B.toStrict (runPut (putInt64le i)) instance FromBytes Int64 where fromBytes mem =- let bs = fromBytes mem- in case bs of- Left e -> Left e- Right x ->- case runGetOrFail getInt64le (B.fromStrict x) of- Left (_, _, e) -> Left e- Right (_, _, x) -> Right x+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case runGetOrFail getInt64le (B.fromStrict x) of+ Left (_, _, e) -> Left e+ Right (_, _, x) -> Right x instance ToBytes Word32 where toBytes i = toBytes $ B.toStrict (runPut (putWord32le i)) instance FromBytes Word32 where fromBytes mem =- let bs = fromBytes mem- in case bs of- Left e -> Left e- Right x ->- case runGetOrFail getWord32le (B.fromStrict x) of- Left (_, _, e) -> Left e- Right (_, _, x) -> Right x+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case runGetOrFail getWord32le (B.fromStrict x) of+ Left (_, _, e) -> Left e+ Right (_, _, x) -> Right x instance ToBytes Word64 where toBytes i = toBytes $ B.toStrict (runPut (putWord64le i)) instance FromBytes Word64 where fromBytes mem =- let bs = fromBytes mem- in case bs of- Left e -> Left e- Right x ->- case runGetOrFail getWord64le (B.fromStrict x) of- Left (_, _, e) -> Left e- Right (_, _, x) -> Right x+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case runGetOrFail getWord64le (B.fromStrict x) of+ Left (_, _, e) -> Left e+ Right (_, _, x) -> Right x instance ToBytes Float where toBytes i = toBytes $ B.toStrict (runPut (putFloatle i)) instance FromBytes Float where fromBytes mem =- let bs = fromBytes mem- in case bs of- Left e -> Left e- Right x ->- case runGetOrFail getFloatle (B.fromStrict x) of- Left (_, _, e) -> Left e- Right (_, _, x) -> Right x+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case runGetOrFail getFloatle (B.fromStrict x) of+ Left (_, _, e) -> Left e+ Right (_, _, x) -> Right x instance ToBytes Double where toBytes i = toBytes $ B.toStrict (runPut (putDoublele i)) instance FromBytes Double where fromBytes mem =- let bs = fromBytes mem- in case bs of- Left e -> Left e- Right x ->- case runGetOrFail getDoublele (B.fromStrict x) of- Left (_, _, e) -> Left e- Right (_, _, x) -> Right x+ case fromBytes mem of+ Left e -> Left e+ Right x ->+ case runGetOrFail getDoublele (B.fromStrict x) of+ Left (_, _, e) -> Left e+ Right (_, _, x) -> Right x
src/extism-pdk.c view
@@ -65,6 +65,9 @@ DEFINE(http_status_code, int32_t) int32_t extism_http_status_code() { return _http_status_code(); } +DEFINE(http_headers, ExtismPointer)+ExtismPointer extism_http_headers() { return _http_headers(); }+ DEFINE(log_info, void, ExtismPointer) void extism_log_info(ExtismPointer p) { return _log_info(p); } DEFINE(log_debug, void, ExtismPointer)@@ -73,3 +76,7 @@ void extism_log_warn(ExtismPointer p) { return _log_warn(p); } DEFINE(log_error, void, ExtismPointer) void extism_log_error(ExtismPointer p) { return _log_error(p); }+DEFINE(log_trace, void, ExtismPointer)+void extism_log_trace(ExtismPointer p) { return _log_trace(p); }+DEFINE(get_log_level, int32_t)+int32_t extism_get_log_level() { return _get_log_level(); }