Skip to main content

pgrx_sql_entity_graph/
positioning_ref.rs

1//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC.
2//LICENSE
3//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc.
4//LICENSE
5//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. <contact@pgcentral.org>
6//LICENSE
7//LICENSE All rights reserved.
8//LICENSE
9//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file.
10/*!
11
12Positioning references for Rust to SQL mapping support.
13
14> Like all of the [`sql_entity_graph`][crate] APIs, this is considered **internal**
15> to the `pgrx` framework and very subject to change between versions. While you may use this, please do it with caution.
16
17*/
18use quote::{ToTokens, quote};
19use std::fmt::Display;
20use syn::parse::{Parse, ParseStream};
21
22#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
23pub enum PositioningRef {
24    FullPath(String),
25    Name(String),
26}
27
28impl Display for PositioningRef {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        match self {
31            PositioningRef::FullPath(i) => f.write_str(i),
32            PositioningRef::Name(i) => f.write_str(i),
33        }
34    }
35}
36
37impl Parse for PositioningRef {
38    fn parse(input: ParseStream) -> Result<Self, syn::Error> {
39        let maybe_litstr: Option<syn::LitStr> = input.parse()?;
40        let found = if let Some(litstr) = maybe_litstr {
41            Self::Name(litstr.value())
42        } else {
43            let path: syn::Path = input.parse()?;
44            let path_str = path.to_token_stream().to_string().replace(' ', "");
45            Self::FullPath(path_str)
46        };
47        Ok(found)
48    }
49}
50
51impl PositioningRef {
52    pub fn section_len_tokens(&self) -> proc_macro2::TokenStream {
53        match self {
54            PositioningRef::FullPath(item) | PositioningRef::Name(item) => quote! {
55                ::pgrx::pgrx_sql_entity_graph::section::u8_len()
56                    + ::pgrx::pgrx_sql_entity_graph::section::str_len(#item)
57            },
58        }
59    }
60
61    pub fn section_writer_tokens(
62        &self,
63        writer: proc_macro2::TokenStream,
64    ) -> proc_macro2::TokenStream {
65        match self {
66            PositioningRef::FullPath(item) => quote! {
67                #writer
68                    .u8(::pgrx::pgrx_sql_entity_graph::section::POSITIONING_REF_FULL_PATH)
69                    .str(#item)
70            },
71            PositioningRef::Name(item) => quote! {
72                #writer
73                    .u8(::pgrx::pgrx_sql_entity_graph::section::POSITIONING_REF_NAME)
74                    .str(#item)
75            },
76        }
77    }
78}
79
80impl ToTokens for PositioningRef {
81    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
82        let toks = match self {
83            PositioningRef::FullPath(item) => quote! {
84                ::pgrx::pgrx_sql_entity_graph::PositioningRef::FullPath(String::from(#item))
85            },
86            PositioningRef::Name(item) => quote! {
87                ::pgrx::pgrx_sql_entity_graph::PositioningRef::Name(String::from(#item))
88            },
89        };
90        toks.to_tokens(tokens);
91    }
92}