extern crate proc_macro;
use generate_request_traits;
use parse_and_generate_api;
use generate_decode_trait_impls;
use generate_default_trait_impls;
use generate_encode_trait_impls;
use TokenStream;
use parse_macro_input;
/// Custom derive for decoding structure or enum from bytes using fluvio protocol format.
/// This assumes all fields implement fluvio decode traits.
///
/// # Examples
///
/// ```
/// use fluvio_protocol::Decoder;
/// use fluvio_protocol::derive::Decode;
///
/// #[derive(Decode)]
/// pub struct SimpleRecord {
/// val: u8
/// }
///
/// let data = [
/// 0x04
/// ];
///
/// let record = SimpleRecord::decode_from(&mut Cursor::new(&data),0).expect("decode");
/// assert_eq!(record.val,4);
///
/// ```
///
///
/// Decode applies to either Struct of Enum. For enum, it implements `TryFrom` trait.
/// Currently it only supports integer variants.
///
/// So this works
///
/// ```
/// #[derive(Decode)]
/// pub enum ThreeChoice {
/// First = 1,
/// Second = 2,
/// Third = 3
/// }
/// ```
///
/// Also, enum without integer literal works as well
/// ```
/// #[derive(Decode)]
/// pub enum ThreeChoice {
/// First,
/// Second,
/// Third
/// }
/// ```
///
/// In this case, 1 is decoded as First, 2 as Second, 3 as Third.
///
/// Currently, mixing enum variants are not supported.
///
///
/// Decode support container and field level attributes.
/// Container level applies to struct.
/// For field attributes
/// * `#[varint]` force decode using varint format.
/// * `#fluvio(min_version = <version>)]` decodes only if version is equal or greater than min_version
/// * `#fluvio(max_version = <version>)]`decodes only if version is less or equal than max_version
///
/// Custom derive for encoding structure or enum to bytes using Kafka protocol format.
/// This assumes all fields(or enum variants) implement kafka encode traits.
///
/// # Examples
///
/// ```
/// use fluvio_protocol::Encoder;
/// use fluvio_protocol::derive::Encode;
///
/// #[derive(Encode)]
/// pub struct SimpleRecord {
/// val: u8
/// }
///
/// let data = vec![];
///
/// let record = SimpleRecord { val: 4};
/// recprd.encode(&mut data,0);
///
/// assert_eq!(data[0],4);
///
/// ```
///
///
/// Encode applys to either Struct of Enum.
///
///
/// Encode respects version attributes. See Decode derive.
///
///
///
/// Custom derive for implementing Request trait.
/// This derives requires `fluvio`
///
/// # Examples
///
/// ```
/// use fluvio_protocol::derive::Decode;
/// use fluvio_protocol::derive::Encode;
/// use fluvio_protocol::api::Request;
/// use fluvio_protocol::derive::RequestApi;
///
/// #[fluvio(default,api_min_version = 5, api_max_version = 6, api_key = 10, response = "SimpleResponse")]
/// #[derive(Request,Encode,Decode,Default)]
/// pub struct SimpleRequest {
/// val: u8
/// }
///
///
/// #[derive(Encode,Decode,Default)]
/// #[fluvio(default)]
/// pub struct TestResponse {
/// pub value: i8,
/// }
///
/// ```
///
/// RequestApi derives respects following attributes in `fluvio`
///
/// * `api_min_version`: min version that API supports. This is required
/// * `api_max_version`: max version that API supports. This is optional.
/// * `api_key`: API number. This is required
/// * `response`: Response struct. This is required
///
/// Custom derive for generating default structure
///
///
/// Example:
///
/// ```
/// #[derive(FluvioDefault)]
/// #[fluvio(default)]
/// pub struct SimpleRecord {
/// #[fluvio(default = "-1" )]
/// val: u8
/// }
///
/// let record = SimpleRecord::default;
/// assert_eq!(record.val,-1);
/// ```
///
/// `default` assignment can be any Rust expression.