{-|
Module      : Net.DNSBase.EDNS.Option.NSID
Description : EDNS Name Server Identifier option (RFC 5001)
Copyright   : (c) Viktor Dukhovni, 2026
License     : BSD-3-Clause
Maintainer  : ietf-dane@dukhovni.org
Stability   : unstable

The NSID EDNS option lets a server identify itself in a reply
— useful for distinguishing between members of an anycast set.
The client sends an empty NSID option to request identification;
the server's reply carries an opaque byte string chosen by the
operator (typically a host name or short tag).
-}

module Net.DNSBase.EDNS.Option.NSID
    ( O_nsid(..)
    ) where

import Net.DNSBase.Decode.Internal.State
import Net.DNSBase.EDNS.Internal.OptNum
import Net.DNSBase.EDNS.Internal.Option
import Net.DNSBase.Encode.Internal.State
import Net.DNSBase.Internal.Present
import Net.DNSBase.Internal.Text
import Net.DNSBase.Internal.Util

-- | The NSID EDNS option
-- ([RFC 5001](https://datatracker.ietf.org/doc/html/rfc5001))
-- — opaque server-chosen bytes identifying the responder.
-- The same option code is used in both directions: a client sends
-- an empty value to ask for identification, the server replies
-- with its identifier (which may contain arbitrary bytes,
-- including non-printable ones).
--
-- The 'Presentable' instance renders the bytes through 'DnsText',
-- producing a quoted character-string when the content is
-- printable and escapes for any non-printable bytes.
newtype O_nsid = O_NSID ShortByteString deriving (O_nsid -> O_nsid -> Bool
(O_nsid -> O_nsid -> Bool)
-> (O_nsid -> O_nsid -> Bool) -> Eq O_nsid
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: O_nsid -> O_nsid -> Bool
== :: O_nsid -> O_nsid -> Bool
$c/= :: O_nsid -> O_nsid -> Bool
/= :: O_nsid -> O_nsid -> Bool
Eq, Int -> O_nsid -> ShowS
[O_nsid] -> ShowS
O_nsid -> String
(Int -> O_nsid -> ShowS)
-> (O_nsid -> String) -> ([O_nsid] -> ShowS) -> Show O_nsid
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> O_nsid -> ShowS
showsPrec :: Int -> O_nsid -> ShowS
$cshow :: O_nsid -> String
show :: O_nsid -> String
$cshowList :: [O_nsid] -> ShowS
showList :: [O_nsid] -> ShowS
Show)

instance Presentable O_nsid where
    -- | Though NSID is an opaque 'ShortByteString', we attempt to present
    -- it as a character string.
    present :: O_nsid -> Builder -> Builder
present (O_NSID ShortByteString
val) = (DnsText -> Builder -> Builder)
-> ShortByteString -> Builder -> Builder
forall a b. Coercible a b => a -> b
coerce (forall a. Presentable a => a -> Builder -> Builder
present @DnsText) ShortByteString
val

instance KnownEdnsOption O_nsid where
    optNum :: forall b -> (b ~ O_nsid) => OptNum
optNum _ = OptNum
NSID
    {-# INLINE optNum #-}
    optEncode :: forall s r. (Typeable r, Eq r, Show r) => O_nsid -> SPut s r
optEncode (O_NSID ShortByteString
bs) = ShortByteString -> SPut s r
forall r s. ErrorContext r => ShortByteString -> SPut s r
putShortByteString ShortByteString
bs
    optDecode :: forall b ->
(b ~ O_nsid) => OptionExtensionVal b -> Int -> SGet EdnsOption
optDecode _ OptionExtensionVal b
_ = O_nsid -> EdnsOption
forall a. KnownEdnsOption a => a -> EdnsOption
EdnsOption (O_nsid -> EdnsOption)
-> (ShortByteString -> O_nsid) -> ShortByteString -> EdnsOption
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> O_nsid
O_NSID (ShortByteString -> EdnsOption)
-> (Int -> SGet ShortByteString) -> Int -> SGet EdnsOption
forall (m :: * -> *) b c a.
Functor m =>
(b -> c) -> (a -> m b) -> a -> m c
<.> Int -> SGet ShortByteString
getShortNByteString