cookbook 2.2.1.0 → 2.3.1.0
raw patch · 2 files changed
+130/−2 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Cookbook.Project.Quill.Quill2: List :: [a] -> Element a
+ Cookbook.Project.Quill.Quill2: QuillMissing :: QuillStatus
+ Cookbook.Project.Quill.Quill2: QuillMultiple :: QuillStatus
+ Cookbook.Project.Quill.Quill2: QuillSuccess :: Quill -> QuillStatus
+ Cookbook.Project.Quill.Quill2: Table :: [(a, a)] -> Element a
+ Cookbook.Project.Quill.Quill2: addItem :: [Quill] -> (String, String, String) -> [Quill]
+ Cookbook.Project.Quill.Quill2: addQuill :: [Quill] -> Quill -> [Quill]
+ Cookbook.Project.Quill.Quill2: addToQuill :: Quill -> (String, String) -> Quill
+ Cookbook.Project.Quill.Quill2: changeItem :: [Quill] -> (String, String, String) -> [Quill]
+ Cookbook.Project.Quill.Quill2: data Element a
+ Cookbook.Project.Quill.Quill2: data QuillStatus
+ Cookbook.Project.Quill.Quill2: decomment :: String -> String
+ Cookbook.Project.Quill.Quill2: getQuill :: [Quill] -> String -> QuillStatus
+ Cookbook.Project.Quill.Quill2: getQuillName :: Quill -> String
+ Cookbook.Project.Quill.Quill2: instance Eq QuillStatus
+ Cookbook.Project.Quill.Quill2: instance Eq a => Eq (Element a)
+ Cookbook.Project.Quill.Quill2: instance Show QuillStatus
+ Cookbook.Project.Quill.Quill2: instance Show a => Show (Element a)
+ Cookbook.Project.Quill.Quill2: lookUp :: [Quill] -> (String, String) -> String
+ Cookbook.Project.Quill.Quill2: pFile :: [String] -> [Quill]
+ Cookbook.Project.Quill.Quill2: pTable :: String -> Quill
+ Cookbook.Project.Quill.Quill2: prepare :: [String] -> String
+ Cookbook.Project.Quill.Quill2: removeItem :: [Quill] -> (String, String) -> [Quill]
+ Cookbook.Project.Quill.Quill2: removeQuill :: [Quill] -> String -> [Quill]
+ Cookbook.Project.Quill.Quill2: toString :: Quill -> String
+ Cookbook.Project.Quill.Quill2: type Quill = (String, Element String)
Files
- Cookbook/Project/Quill/Quill2.hs +128/−0
- cookbook.cabal +2/−2
+ Cookbook/Project/Quill/Quill2.hs view
@@ -0,0 +1,128 @@+{- |+ Module : Cookbook.Project.Quill.Quill2+ Copyright : (c) 2014 by Nate Pisarski+ License : BSD3+ Maintainer : nathanpisarski@gmail.com+ Stability : Stable+ Portability : Portable (Cookbook+Another library for managing databases. It GREATLY breaks compatibility with Quill, and it will eventually deprecate Quill. It's a whitespace-independant string-based flat file language for database information. Some advantages that Quill2 has over Quill include: Record database entries, list support, better commenting support, more complete API, and greater error handling / safety.+-}++module Cookbook.Project.Quill.Quill2 where++import qualified Cookbook.Essential.Common as Cm+import qualified Cookbook.Essential.Continuous as Ct++import qualified Cookbook.Ingredients.Lists.Modify as Md+import qualified Cookbook.Ingredients.Lists.Access as Ac+import qualified Cookbook.Ingredients.Lists.Encompass as En+import qualified Cookbook.Ingredients.Tupples.Look as Lk++-- Data types and Instances+-- | The body of a table or list.+data Element a = List [a] | Table [(a,a)] deriving (Eq, Show)++-- | Helper type. Binds a name to a body.+type Quill = (String,Element String)+ +-- Preprocessing functions - Turning raw text into a more easily workable format.++-- | Strip comments from a sanitized string. Comments start with /* and end with */.+decomment :: String -> String+decomment = (`Ct.splice` ("/*", "*/"))++-- | Prepare the lines of a file for processing.+prepare :: [String] -> String+prepare = decomment . (`Ct.remove` '\n') . unlines++-- Text processing - Turning the preprocessed text into data.++-- | Process a single entry in the database into a Table.+pTable :: String -> Quill+pTable x = typ+ where+ name = Md.between (Ct.before x '{') ('(',')') --table(name) or list(name)+ typ = (name,if (Ct.before x '{') `Ac.contains` "table" then Table (parseTables body) else List body)+ body = Md.splitOn (En.encompassing x ('{','}')) ';'+ quoted y = if ('`','\'') `Ac.surrounds` y then En.encompassing x ('`','\'') else Ct.remove y ' '+ parseTables [] = []+ parseTables (x:xs) =(quoted $ Ct.before x ':', Ct.after x ':') : parseTables xs++-- | Turn the lines of a file into a list of tables, AKA a Database.+pFile :: [String] -> [Quill]+pFile x = case allTables of+ [] -> []+ (y:ys) -> pTable y : pFile ys+ where+ prepared = prepare x+ allTables = Md.splitOn prepared '}'++-- API functions for creating and reading tables.++data QuillStatus = QuillSuccess Quill | QuillMissing | QuillMultiple deriving (Eq,Show)++getQuillName :: Quill -> String+getQuillName = fst++getQuill :: [Quill] -> String -> QuillStatus+getQuill [] _ = QuillMissing+getQuill (x:xs) c+ | Ac.count (map getQuillName (x:xs)) c > 1 = QuillMultiple+ | getQuillName x == c = QuillSuccess x+ | otherwise = getQuill xs c++lookUp :: [Quill] -> (String, String) -> String+lookUp x (a,b) = case (getQuill x a) of+ QuillMissing -> error $ "Table not found."+ QuillMultiple -> error $ "Multiple values of " ++ a ++ " detected. Database eror, fix manually."+ (QuillSuccess (c,d)) -> case d of+ (List f) -> error "Cannot look up the value of a list."+ (Table f) -> let c = Lk.lookList f b in if (c == []) then (error $ "Item " ++ b ++ " not found in table " ++ a) else (if (length c > 1) then multipleInnerError else (head c))+ where multipleInnerError = error $ "Multiple values of " ++ b ++ " found in table " ++ a ++ ". Database corrupted, change manually."++removeQuill :: [Quill] -> String -> [Quill]+removeQuill [] _ = []+removeQuill ((x,y):xs) c+ | x == c = removeQuill xs c -- See [Q2N1]+ | otherwise = (x,y) : removeQuill xs c++removeItem :: [Quill] -> (String, String) -> [Quill]+removeItem x (a,b) = case (getQuill x a) of+ QuillSuccess (c,j) -> case j of+ (Table d) -> (c,(Table [(y,t) | (y,t) <- d, y /= b])) : (removeQuill x a)+ (List d) -> (c,List $ Ct.remove d c) : removeQuill x a+ _ -> (let l = lookUp x (a,b) in x) -- This goes against everything that haskell means.++addQuill :: [Quill] -> Quill -> [Quill]+addQuill x c = c : x++addToQuill :: Quill -> (String, String) -> Quill+addToQuill (x,b) c = case b of+ (Table z) -> (x, Table (c:z))+ (List z) -> (x, List (z))++addItem :: [Quill] -> (String, String, String) -> [Quill]+addItem x (a, b, c)= case getQuill x a of+ QuillSuccess (y, ys) -> case ys of+ (Table d) -> (y,Table $ (b,c) : d) : removeQuill x a+ (List d) -> (y,List $ (c:d)) : removeQuill x a+ QuillMultiple -> error "Multiple found"+ QuillMissing -> error "Not found quill!"++changeItem :: [Quill] -> (String, String, String) -> [Quill]+changeItem x (a,b,c) = addItem (removeItem x (a,b)) (a,b,c)++-- Helping functions for writing / reading to files.+-- | Turn a Quill table into a string.+toString :: Quill -> String+toString (nm,typ) = case typ of+ (List a) -> ("list(" ++ nm ++ "){" ++ (Cm.flt (map (\c -> (c ++ ";")) a))) ++ "}"+ (Table a) -> ("table(" ++ nm ++ "){" ++ (Cm.flt $ stringify a)) ++ "}"+ where+ stringify [] = []+ stringify ((a,b):xs) = (a ++ ":" ++ b ++ ";") : stringify xs++-- [Q2N1]+-- I had a long debate about this function. What it does is removes tables, but it will remove ALL tables. Since+-- Quill2 treats multiple tables of the same name as an error, I'm choosing to make it a sanitization function as+-- well. Database clients beware.
cookbook.cabal view
@@ -3,7 +3,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 2.2.1.0+version: 2.3.1.0 synopsis: Tiered general-purpose libraries with domain-specific applications. description: Cookbook is a line of libraries covering a wide variety of Haskell applications. Every application that I make, I add its functions to Cookbook, turning Cookbook into an all-encompassing general-purpose library over time. The claim-to-fame for the library is its use of overloaded typeclasses, called "Continuities". license: BSD3@@ -16,7 +16,7 @@ build-type: Simple cabal-version: >=1.8 library - exposed-modules: Cookbook.Essential.Common, Cookbook.Essential.Continuous, Cookbook.Essential.IO, Cookbook.Project.Configuration.Configuration, Cookbook.Project.Preprocess.Preprocess, Cookbook.Ingredients.Functional.Break, Cookbook.Ingredients.Lists.Access, Cookbook.Ingredients.Lists.Modify, Cookbook.Ingredients.Lists.Stats, Cookbook.Ingredients.Tupples.Look, Cookbook.Ingredients.Tupples.Assemble, Cookbook.Recipes.Sanitize, Cookbook.Recipes.Math,Cookbook.Recipes.DataStructures,Cookbook.Recipes.Algorithm, Cookbook.Project.Quill.Quill, Cookbook.Recipes.Cline, Cookbook.Ingredients.Lists.Encompass+ exposed-modules: Cookbook.Essential.Common, Cookbook.Essential.Continuous, Cookbook.Essential.IO, Cookbook.Project.Configuration.Configuration, Cookbook.Project.Preprocess.Preprocess, Cookbook.Ingredients.Functional.Break, Cookbook.Ingredients.Lists.Access, Cookbook.Ingredients.Lists.Modify, Cookbook.Ingredients.Lists.Stats, Cookbook.Ingredients.Tupples.Look, Cookbook.Ingredients.Tupples.Assemble, Cookbook.Recipes.Sanitize, Cookbook.Recipes.Math,Cookbook.Recipes.DataStructures,Cookbook.Recipes.Algorithm, Cookbook.Project.Quill.Quill, Cookbook.Recipes.Cline, Cookbook.Ingredients.Lists.Encompass, Cookbook.Project.Quill.Quill2 build-depends: base ==4.6.*, directory, strict source-repository head type: git