#![allow(
    clippy::elidable_lifetime_names,
    clippy::needless_lifetimes,
    clippy::uninlined_format_args
)]

#[macro_use]
mod snapshot;

mod debug;

use syn::{parse_quote, TraitItemFn};

#[test]
fn test_by_value() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn by_value(self: Self);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Typed(
            Type::Path {
                path: Path {
                    segments: [
                        PathSegment {
                            ident: "Self",
                        },
                    ],
                },
            },
        ),
    })
    "#);
}

#[test]
fn test_by_mut_value() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn by_mut(mut self: Self);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        mutability: Some,
        kind: ReceiverKind::Typed(
            Type::Path {
                path: Path {
                    segments: [
                        PathSegment {
                            ident: "Self",
                        },
                    ],
                },
            },
        ),
    })
    "#);
}

#[test]
fn test_by_ref() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn by_ref(self: &Self);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Typed(
            Type::Reference {
                elem: Type::Path {
                    path: Path {
                        segments: [
                            PathSegment {
                                ident: "Self",
                            },
                        ],
                    },
                },
            },
        ),
    })
    "#);
}

#[test]
fn test_by_box() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn by_box(self: Box<Self>);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Typed(
            Type::Path {
                path: Path {
                    segments: [
                        PathSegment {
                            ident: "Box",
                            arguments: PathArguments::AngleBracketed {
                                args: [
                                    GenericArgument::Type(Type::Path {
                                        path: Path {
                                            segments: [
                                                PathSegment {
                                                    ident: "Self",
                                                },
                                            ],
                                        },
                                    }),
                                ],
                            },
                        },
                    ],
                },
            },
        ),
    })
    "#);
}

#[test]
fn test_by_pin() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn by_pin(self: Pin<Self>);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Typed(
            Type::Path {
                path: Path {
                    segments: [
                        PathSegment {
                            ident: "Pin",
                            arguments: PathArguments::AngleBracketed {
                                args: [
                                    GenericArgument::Type(Type::Path {
                                        path: Path {
                                            segments: [
                                                PathSegment {
                                                    ident: "Self",
                                                },
                                            ],
                                        },
                                    }),
                                ],
                            },
                        },
                    ],
                },
            },
        ),
    })
    "#);
}

#[test]
fn test_explicit_type() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn explicit_type(self: Pin<MyType>);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Typed(
            Type::Path {
                path: Path {
                    segments: [
                        PathSegment {
                            ident: "Pin",
                            arguments: PathArguments::AngleBracketed {
                                args: [
                                    GenericArgument::Type(Type::Path {
                                        path: Path {
                                            segments: [
                                                PathSegment {
                                                    ident: "MyType",
                                                },
                                            ],
                                        },
                                    }),
                                ],
                            },
                        },
                    ],
                },
            },
        ),
    })
    "#);
}

#[test]
fn test_value_shorthand() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn value_shorthand(self);
    };
    snapshot!(&sig.inputs[0], @"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Value,
    })
    ");
}

#[test]
fn test_mut_value_shorthand() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn mut_value_shorthand(mut self);
    };
    snapshot!(&sig.inputs[0], @"
    FnArg::Receiver(Receiver {
        mutability: Some,
        kind: ReceiverKind::Value,
    })
    ");
}

#[test]
fn test_ref_shorthand() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn ref_shorthand(&self);
    };
    snapshot!(&sig.inputs[0], @"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Reference(
            None,
            None,
        ),
    })
    ");
}

#[test]
fn test_ref_shorthand_with_lifetime() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn ref_shorthand(&'a self);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Reference(
            Some(Lifetime {
                ident: "a",
            }),
            None,
        ),
    })
    "#);
}

#[test]
fn test_ref_mut_shorthand() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn ref_mut_shorthand(&mut self);
    };
    snapshot!(&sig.inputs[0], @"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Reference(
            None,
            Some,
        ),
    })
    ");
}

#[test]
fn test_ref_mut_shorthand_with_lifetime() {
    let TraitItemFn { sig, .. } = parse_quote! {
        fn ref_mut_shorthand(&'a mut self);
    };
    snapshot!(&sig.inputs[0], @r#"
    FnArg::Receiver(Receiver {
        kind: ReceiverKind::Reference(
            Some(Lifetime {
                ident: "a",
            }),
            Some,
        ),
    })
    "#);
}
