NanoID (empty) → 1.0.0
raw patch · 6 files changed
+166/−0 lines, 6 filesdep +NanoIDdep +basedep +bytestringsetup-changed
Dependencies added: NanoID, base, bytestring, extra, mwc-random, optparse-applicative
Files
- LICENSE +30/−0
- NanoID.cabal +39/−0
- Setup.hs +2/−0
- app/Main.hs +24/−0
- app/Options.hs +47/−0
- src/Data/NanoID.hs +24/−0
+ LICENSE view
@@ -0,0 +1,30 @@+NanoID, lib & app, Copyright (c) 2021, Michel Boucey++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Michel Boucey nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ NanoID.cabal view
@@ -0,0 +1,39 @@+name: NanoID+version: 1.0.0+synopsis: NanoID generator+description: Library and CLI tool for NanoID generation+license: BSD3+license-file: LICENSE+author: Michel Boucey+maintainer: michel.boucey@gmail.com+copyright: (c) 2021 - Michel Boucey+category: Data+build-type: Simple+cabal-version: >=1.10++Tested-With: GHC ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.1 || ==8.10.4 || ==9.0.1++source-repository head+ type: git+ location: git://github.com/MichelBoucey/NanoID.git++library+ exposed-modules: Data.NanoID+ build-depends: base >=4.7 && <4.15+ , bytestring >= 0.10 && < 0.12+ , extra >= 1.6 && < 1.8+ , mwc-random >= 0.13 && < 0.16+ hs-source-dirs: src+ default-language: Haskell2010++executable nanoid+ main-is: Main.hs+ other-modules: Options+ build-depends: base >=4.7 && <4.15+ , bytestring >= 0.10 && < 0.12+ , mwc-random >= 0.13 && < 0.16+ , NanoID+ , optparse-applicative >= 0.14 && < 0.17+ hs-source-dirs: app+ default-language: Haskell2010+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,24 @@+{-# LANGUAGE RecordWildCards #-}++import Control.Monad+import qualified Data.ByteString.Char8 as C+import Options.Applicative+import System.Exit+import System.Random.MWC++import Data.NanoID+import Options++main :: IO ()+main = do+ Options{..} <- execParser opts+ if length > 21+ then putStrLn "The length of NanoID is less or equal to 21" >> exitFailure+ else do+ let alphabet' = Alphabet { unAlphabet = C.pack alphabet }+ replicateM_ quantity $+ unNanoID <$> (createSystemRandom >>= customNanoID alphabet' length) >>= putNanoID newline+ exitSuccess+ where+ putNanoID n = if n then C.putStrLn else C.putStr+
+ app/Options.hs view
@@ -0,0 +1,47 @@+module Options where++import qualified Data.ByteString.Char8 as C+import Data.NanoID+import Options.Applicative++data Options =+ Options+ { alphabet :: String+ , length :: Int+ , quantity :: Int+ , newline :: Bool+ }++opts :: ParserInfo Options+opts = info (options <**> helper)+ ( fullDesc+ <> progDesc "NanoID generator"+ <> header "nanoid v1.0.0, (c) Michel Boucey 2021" )++options :: Parser Options+options =+ Options+ <$>+ strOption+ ( short 'a'+ <> long "alphabet"+ <> help "Use an alternative alphabet (ascii chars only)"+ <> value (C.unpack $ unAlphabet defaultAlphabet) )+ <*>+ option auto+ ( short 'l'+ <> long "length"+ <> help "Get shorter NanoID"+ <> value 21 )+ <*>+ option auto+ ( short 'q'+ <> long "quantity"+ <> help "Quantity of NanoID to generate"+ <> value 1 )+ <*>+ flag True False+ ( short 'n'+ <> long "newline"+ <> help "Do not output the trailing newline" )+
+ src/Data/NanoID.hs view
@@ -0,0 +1,24 @@+module Data.NanoID where++import Control.Monad+import qualified Data.ByteString.Char8 as C+import System.Random.MWC++newtype NanoID = NanoID { unNanoID :: C.ByteString } deriving (Eq, Show)++newtype Alphabet = Alphabet { unAlphabet :: C.ByteString } deriving (Eq, Show)++type Length = Int++defaultAlphabet :: Alphabet+defaultAlphabet = Alphabet (C.pack "ABCDEFGHIJKLMNOPKRSTUVWXYZ_-abcdefghijklmnopqrstuvwxyz")++nanoID :: IO NanoID+nanoID = createSystemRandom >>= customNanoID defaultAlphabet 21++customNanoID :: Alphabet -> Length -> GenIO-> IO NanoID+customNanoID a l g = do+ let acs = unAlphabet a+ al = C.length acs+ NanoID . C.pack <$> replicateM l ((\r -> C.index acs (r-1)) <$> uniformR (1,al) g)+