Instances for NonEmpty Array and NonEmpty List
dgendill opened this issue · 4 comments
Would it make sense to have instances for NonEmpty Array and NonEmpty List?
instance encodeJsonNonEmptyArray :: (EncodeJson a) => EncodeJson (NonEmpty Array a) where
encodeJson (NonEmpty h t) = encodeJson $ cons h t
instance encodeJsonNonEmptyList :: (EncodeJson a) => EncodeJson (NonEmpty List a) where
encodeJson (NonEmpty h t) = encodeJson $ cons h (toUnfoldable t)I think something like that would make sense 👍
Maybe?
instance encodeJsonNonEmptyFoldable :: (EncodeJson a, Foldable f) => EncodeJson (NonEmpty f a) where
encodeJson (NonEmpty h t) =
encodeJson $ StrMap.fromFoldable [ Tuple "head" h, Tuple "tail" $ foldMap Arr.singleton t ]And
instance decodeJsonNonEmptyUnfoldable :: (DecodeJson a, Unfoldable f) => DecodeJson (NonEmpty f a) where
decodeJson js = decodeJson >=> \obj -> do
h <- obj .? "head"
tl <- map (unfoldr (Arr.uncons >>> map (\{head, tail} -> Tuple head tail)) $ obj .? "tail"
pure $ h :| tl I like the idea of having a way to encode/decode any Foldable/Unfoldable. Would having a specific instance for Array and List, along with the more generalized form work? My thought is that a NonEmpty Array or a NonEmpty List should be turned into a JSON array, so that the PureScript types more closely resemble the underlying javascript types.
For my use case, I'd like to model the configuration object to create a RTCIceServer and the urls property can be either a string or an array of strings (presumably not an empty array). In modeling that, I thought this structure would be good.
data ServerType
= STUN { urls :: NonEmpty Array String }
| TURN { urls :: NonEmpty Array String, credentialType :: Maybe String, credential :: Maybe String, username :: Maybe String }
instance serverTypeEncodeJson :: EncodeJson ServerType where
encodeJson (STUN s) = jsonSingletonObject "urls" (encodeJson s.urls)
encodeJson (TURN t) = (
"urls" := t.urls
~> "credentialType" := t.credentialType
~> "credential" := t.credential
~> "username" := t.username
~> jsonEmptyObject
)So then I could encode the ServerType into Json and pass the Json into the FFI to create an RTCIceServer.