use crate::datastreams::Payload;

/// A trait for types that can be converted into arguments for a
/// [`StreamCandidate`](crate::datastreams::StreamCandidate).
pub trait IArguments: core::fmt::Debug {
    /// Converts the implementing type into an optional [`Payload`].
    ///
    /// If `Some(payload)` is returned, the payload will be sent as arguments when initiating the
    /// stream.
    fn into_arguments(self) -> Option<Payload>;
}

/// No arguments were set yet for the [`ConnectionBuilder`](crate::datastreams::ConnectionBuilder)
/// or [`StreamCandidate`](crate::datastreams::StreamCandidate).
#[derive(Debug, Clone)]
pub struct NoArguments;
impl IArguments for NoArguments {
    fn into_arguments(self) -> Option<Payload> {
        None
    }
}

impl IArguments for Payload {
    fn into_arguments(self) -> Option<Payload> {
        Some(self)
    }
}

impl IArguments for Option<Payload> {
    fn into_arguments(self) -> Option<Payload> {
        self
    }
}

/// This is set as the arguments to be sent on
/// [`StreamCandidate`](crate::datastreams::StreamCandidate)s that are received as a response to a
/// connection request, as the client's opportunity to set arguments
/// ([`ConnectionBuilder::with_arguments`](crate::datastreams::ConnectionBuilder::with_arguments))
/// has already passed.
#[derive(Debug, Clone)]
pub struct ArgumentsDisallowed;
impl IArguments for ArgumentsDisallowed {
    fn into_arguments(self) -> Option<Payload> {
        None
    }
}
