From 11fca56c179ce2da7d279293a6b3c7d1bb35c74c Mon Sep 17 00:00:00 2001 From: Sam Truzjan Date: Tue, 8 Apr 2014 04:53:22 +0400 Subject: Hide Tree.hs module --- src/System/Torrent/Tree.hs | 83 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/System/Torrent/Tree.hs (limited to 'src/System') diff --git a/src/System/Torrent/Tree.hs b/src/System/Torrent/Tree.hs new file mode 100644 index 00000000..41cfb360 --- /dev/null +++ b/src/System/Torrent/Tree.hs @@ -0,0 +1,83 @@ +-- | +-- Copyright : (c) Sam Truzjan 2013 +-- License : BSD3 +-- Maintainer : pxqr.sta@gmail.com +-- Stability : experimental +-- Portability : portable +-- +-- Directory tree can be used to easily manipulate file layout info. +-- +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE DeriveDataTypeable #-} +module System.Torrent.Tree + ( -- * Directory tree + DirTree (..) + + -- * Construction + , build + + -- * Query + , System.Torrent.Tree.lookup + , lookupDir + , fileNumber + , dirNumber + ) where + +import Data.ByteString as BS +import Data.ByteString.Char8 as BC +import Data.Foldable +import Data.List as L +import Data.Map as M +import Data.Monoid + +import Data.Torrent + + +-- | 'DirTree' is more convenient form of 'LayoutInfo'. +data DirTree a = Dir { children :: Map ByteString (DirTree a) } + | File { node :: FileInfo a } + deriving Show + +-- | Build directory tree from a list of files. +build :: LayoutInfo -> DirTree () +build SingleFile {liFile = FileInfo {..}} = Dir + { children = M.singleton fiName (File fi) } + where + fi = FileInfo fiLength fiMD5Sum () +build MultiFile {..} = Dir $ M.singleton liDirName files + where + files = Dir $ M.fromList $ L.map mkFileEntry liFiles + mkFileEntry FileInfo {..} = (L.head fiName, ent) -- TODO FIXME + where + ent = File $ FileInfo fiLength fiMD5Sum () + +--decompress :: DirTree () -> [FileInfo ()] +--decompress = undefined + +-- TODO pretty print + +-- | Lookup file by path. +lookup :: [FilePath] -> DirTree a -> Maybe (DirTree a) +lookup [] t = Just t +lookup (p : ps) (Dir m) | Just subTree <- M.lookup (BC.pack p) m + = System.Torrent.Tree.lookup ps subTree +lookup _ _ = Nothing + +-- | Lookup directory by path. +lookupDir :: [FilePath] -> DirTree a -> Maybe [(ByteString, DirTree a)] +lookupDir ps d = do + subTree <- System.Torrent.Tree.lookup ps d + case subTree of + File _ -> Nothing + Dir es -> Just $ M.toList es + +-- | Get total count of files in directory and subdirectories. +fileNumber :: DirTree a -> Sum Int +fileNumber File {..} = Sum 1 +fileNumber Dir {..} = foldMap fileNumber children + +-- | Get total count of directories in the directory and subdirectories. +dirNumber :: DirTree a -> Sum Int +dirNumber File {..} = Sum 0 +dirNumber Dir {..} = Sum 1 <> foldMap dirNumber children -- cgit v1.2.3