Ich möchte Conduit
in einer Einstellung verwenden, wo ich eine Binärdatei lesen, überprüfen Sie, dass es den richtigen Header hat, und dann an den verbleibenden Daten in der Datei arbeiten.Conduit, die Dateikopf überprüft
Wenn Sie versuchen, einen Conduit zu schreiben, der den Header prüft und dann den Rest der Daten an die folgenden Conduits überträgt, stoße ich in Schwierigkeiten. Ich habe sie leben in einem Either String
Monad für einige Ausnahmen. Hier ist eine vereinfachte Version des Codes (ich bin mir bewusst, es gibt ein Condiut.Attoparsec
Modul, aber jetzt würde Ich mag es schreiben selbst):
import Conduit (ConduitM, mapC, mapM_C, takeWhileCE)
import Data.ByteString.Conversion (toByteString')
separator :: ByteString
separator = toByteString' '#'
check :: ByteString -> Either String()
confirmHeader :: ConduitM ByteString ByteString (Either String)()
confirmHeader = do
takeWhileC (/= separator) .| mapM_C check
mapC id
separator
ist eine vordefinierte ByteString
, die das Ende des Headers signalisiert. Die Zeile mapC id
soll den Rest des Streams weiterleiten, wenn der Header auscheckt. Ich habe die unwichtigen Details von check
weggelassen.
Der Teil, der die Kopfzeile überprüft, funktioniert. Die letzte Zeile, abgesehen von unelegant und nicht-idiomatisch, funktioniert nicht. so etwas wie
runConduit $ yield (toByteString' "header#rest") .| confirmHeader .| sinkList
Lauf Gibt Right []
statt Right ["rest"]
, wie ich gehofft hatte. Irgendwelche Ideen?
Great! Als kleines Detail habe ich mich für takeWhileCE entschieden, aber ich werde es mit Conduit.Binary vergleichen. – jorgen
'takeWhileCE' sollte funktionieren: Eigentlich wollte ich das verwenden, aber ich habe seinen Namen vergessen und Conduit.Binary kam zuerst auf Hacker. –
Ok! Kannst du dir übrigens etwas eleganteres vorstellen als 'mapC id', oder ist das Standard? Entschuldigung, wenn dies jetzt aus dem Thema ist .. – jorgen