{-# OPTIONS --without-K --safe #-} module Data.String.Printf where open import Data.List using (List; []; _∷_; foldr) open import Data.String hiding (show) open import Data.Nat hiding (_≟_) open import Data.Char as Char using (Char) import Level open import Relation.Nullary infixr 6 _%_ record FormatUnit : Set (Level.suc Level.zero) where constructor _%_ field marker : Char {type} : Set conv : type → String open FormatUnit public module Internal where data Formatter : Set (Level.suc Level.zero) where chr : Char → Formatter cnv : (t : Set) → (t → String) → Formatter formatUnitTy : Formatter → Set → Set formatUnitTy (chr _) xs = xs formatUnitTy (cnv t _) xs = t → xs formatTy : List Formatter → Set formatTy = foldr formatUnitTy String toFormat : List FormatUnit → List Char → List Formatter toFormat fs [] = [] toFormat fs ('%' ∷ x ∷ xs) = go fs x xs where go : List FormatUnit → Char → List Char → List Formatter go [] x xs = chr x ∷ toFormat fs xs go (f ∷ fs) x xs with marker f Char.≟ x go (f ∷ _ ) x xs | yes p = cnv _ (conv f) ∷ toFormat fs xs go (f ∷ fs) x xs | no ¬p = go fs x xs toFormat fs (x ∷ xs) = chr x ∷ toFormat fs xs printf : (fs : List FormatUnit) → (xs : String) → formatTy (toFormat fs (toList xs)) printf fs xs = go "" (toFormat fs (toList xs)) where go : String → (xs : List Formatter) → formatTy xs go k [] = k go k (chr x ∷ xs) = go (k ++ fromList (x ∷ [])) xs go k (cnv _ c ∷ xs) = λ x → go (k ++ c x) xs import Data.Nat.Show open import Function standard : List FormatUnit standard = 'i' % Data.Nat.Show.show ∷ 's'% id ∷ [] module Printf (fs : List FormatUnit) where printf : (xs : String) → Internal.formatTy (Internal.toFormat fs (toList xs)) printf = Internal.printf fs