scylladb_parse/statements/
security.rs

1use super::*;
2use std::collections::BTreeSet;
3
4#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
5#[parse_via(TaggedRoleStatement)]
6pub enum RoleStatement {
7    Create(CreateRoleStatement),
8    Alter(AlterRoleStatement),
9    Drop(DropRoleStatement),
10    Grant(GrantRoleStatement),
11    Revoke(RevokeRoleStatement),
12    List(ListRolesStatement),
13}
14
15impl TryFrom<TaggedRoleStatement> for RoleStatement {
16    type Error = anyhow::Error;
17
18    fn try_from(value: TaggedRoleStatement) -> Result<Self, Self::Error> {
19        Ok(match value {
20            TaggedRoleStatement::Create(v) => RoleStatement::Create(v.try_into()?),
21            TaggedRoleStatement::Alter(v) => RoleStatement::Alter(v.try_into()?),
22            TaggedRoleStatement::Drop(v) => RoleStatement::Drop(v.try_into()?),
23            TaggedRoleStatement::Grant(v) => RoleStatement::Grant(v.try_into()?),
24            TaggedRoleStatement::Revoke(v) => RoleStatement::Revoke(v.try_into()?),
25            TaggedRoleStatement::List(v) => RoleStatement::List(v.try_into()?),
26        })
27    }
28}
29
30#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
31#[tokenize_as(RoleStatement)]
32pub enum TaggedRoleStatement {
33    Create(TaggedCreateRoleStatement),
34    Alter(TaggedAlterRoleStatement),
35    Drop(TaggedDropRoleStatement),
36    Grant(TaggedGrantRoleStatement),
37    Revoke(TaggedRevokeRoleStatement),
38    List(TaggedListRolesStatement),
39}
40
41impl Parse for TaggedRoleStatement {
42    type Output = Self;
43    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
44        Ok(if s.check::<CREATE>() {
45            Self::Create(s.parse()?)
46        } else if s.check::<ALTER>() {
47            Self::Alter(s.parse()?)
48        } else if s.check::<DROP>() {
49            Self::Drop(s.parse()?)
50        } else if s.check::<GRANT>() {
51            Self::Grant(s.parse()?)
52        } else if s.check::<REVOKE>() {
53            Self::Revoke(s.parse()?)
54        } else if s.check::<LIST>() {
55            Self::List(s.parse()?)
56        } else {
57            anyhow::bail!("Expected a role statement, found {}", s.info())
58        })
59    }
60}
61
62impl Display for RoleStatement {
63    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
64        match self {
65            Self::Create(stmt) => stmt.fmt(f),
66            Self::Alter(stmt) => stmt.fmt(f),
67            Self::Drop(stmt) => stmt.fmt(f),
68            Self::Grant(stmt) => stmt.fmt(f),
69            Self::Revoke(stmt) => stmt.fmt(f),
70            Self::List(stmt) => stmt.fmt(f),
71        }
72    }
73}
74
75#[derive(ParseFromStr, Clone, Debug, Ord, PartialOrd, Eq, ToTokens)]
76pub enum RoleOpt {
77    Password(LitStr),
78    Login(bool),
79    Superuser(bool),
80    Options(MapLiteral),
81    AccessToDatacenters(SetLiteral),
82    AccessToAllDatacenters,
83}
84
85impl RoleOpt {
86    pub fn password<T: Into<LitStr>>(password: T) -> Self {
87        Self::Password(password.into())
88    }
89
90    pub fn login(login: bool) -> Self {
91        Self::Login(login)
92    }
93
94    pub fn superuser(superuser: bool) -> Self {
95        Self::Superuser(superuser)
96    }
97
98    pub fn options<T: Into<MapLiteral>>(options: T) -> Self {
99        Self::Options(options.into())
100    }
101
102    pub fn access_to_datacenters<T: Into<SetLiteral>>(datacenters: T) -> Self {
103        Self::AccessToDatacenters(datacenters.into())
104    }
105
106    pub fn access_to_all_datacenters() -> Self {
107        Self::AccessToAllDatacenters
108    }
109}
110
111impl PartialEq for RoleOpt {
112    fn eq(&self, other: &Self) -> bool {
113        core::mem::discriminant(self) == core::mem::discriminant(other)
114    }
115}
116
117impl Parse for RoleOpt {
118    type Output = Self;
119    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
120        Ok(if s.parse::<Option<(ACCESS, TO, ALL, DATACENTERS)>>()?.is_some() {
121            Self::AccessToAllDatacenters
122        } else if s.parse::<Option<(ACCESS, TO, DATACENTERS)>>()?.is_some() {
123            Self::AccessToDatacenters(s.parse()?)
124        } else if let Some(m) = s.parse_from::<If<(OPTIONS, Equals), MapLiteral>>()? {
125            Self::Options(m)
126        } else if let Some(b) = s.parse_from::<If<(LOGIN, Equals), bool>>()? {
127            Self::Login(b)
128        } else if let Some(b) = s.parse_from::<If<(SUPERUSER, Equals), bool>>()? {
129            Self::Superuser(b)
130        } else if let Some(p) = s.parse_from::<If<(PASSWORD, Equals), LitStr>>()? {
131            Self::Password(p)
132        } else {
133            anyhow::bail!("Expected a role option, found {}", s.info())
134        })
135    }
136}
137
138impl Display for RoleOpt {
139    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
140        match self {
141            Self::Password(s) => write!(f, "PASSWORD = {}", s),
142            Self::Login(b) => write!(f, "LOGIN = {}", b),
143            Self::Superuser(b) => write!(f, "SUPERUSER = {}", b),
144            Self::Options(m) => write!(f, "OPTIONS = {}", m),
145            Self::AccessToDatacenters(s) => write!(f, "ACCESS TO DATACENTERS {}", s),
146            Self::AccessToAllDatacenters => write!(f, "ACCESS TO ALL DATACENTERS"),
147        }
148    }
149}
150
151pub trait RoleOptBuilderExt {
152    fn role_opts(&mut self) -> &mut Option<BTreeSet<RoleOpt>>;
153
154    fn password(&mut self, p: impl Into<LitStr>) -> &mut Self {
155        self.role_opts()
156            .get_or_insert_with(Default::default)
157            .insert(RoleOpt::Password(p.into()));
158        self
159    }
160
161    fn login(&mut self, b: bool) -> &mut Self {
162        self.role_opts()
163            .get_or_insert_with(Default::default)
164            .insert(RoleOpt::Login(b));
165        self
166    }
167
168    fn superuser(&mut self, b: bool) -> &mut Self {
169        self.role_opts()
170            .get_or_insert_with(Default::default)
171            .insert(RoleOpt::Superuser(b));
172        self
173    }
174
175    fn role_options(&mut self, m: impl Into<MapLiteral>) -> &mut Self {
176        self.role_opts()
177            .get_or_insert_with(Default::default)
178            .insert(RoleOpt::Options(m.into()));
179        self
180    }
181
182    fn access_to_datacenters(&mut self, s: impl Into<SetLiteral>) -> &mut Self {
183        self.role_opts()
184            .get_or_insert_with(Default::default)
185            .insert(RoleOpt::AccessToDatacenters(s.into()));
186        self
187    }
188
189    fn access_to_all_datacenters(&mut self) -> &mut Self {
190        self.role_opts()
191            .get_or_insert_with(Default::default)
192            .insert(RoleOpt::AccessToAllDatacenters);
193        self
194    }
195}
196
197#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
198#[builder(setter(strip_option))]
199#[parse_via(TaggedCreateRoleStatement)]
200pub struct CreateRoleStatement {
201    #[builder(setter(name = "set_if_not_exists"), default)]
202    pub if_not_exists: bool,
203    #[builder(setter(into))]
204    pub name: Name,
205    #[builder(default)]
206    pub options: Option<BTreeSet<RoleOpt>>,
207}
208
209impl TryFrom<TaggedCreateRoleStatement> for CreateRoleStatement {
210    type Error = anyhow::Error;
211    fn try_from(value: TaggedCreateRoleStatement) -> Result<Self, Self::Error> {
212        Ok(Self {
213            if_not_exists: value.if_not_exists,
214            name: value.name.into_value()?,
215            options: value.options.map(|v| v.into_value()).transpose()?,
216        })
217    }
218}
219
220#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
221#[builder(setter(strip_option))]
222#[tokenize_as(CreateRoleStatement)]
223pub struct TaggedCreateRoleStatement {
224    #[builder(setter(name = "set_if_not_exists"), default)]
225    pub if_not_exists: bool,
226    pub name: Tag<Name>,
227    #[builder(default)]
228    pub options: Option<Tag<BTreeSet<RoleOpt>>>,
229}
230
231impl CreateRoleStatementBuilder {
232    /// Set IF NOT EXISTS on the statement.
233    /// To undo this, use `set_if_not_exists(false)`.
234    pub fn if_not_exists(&mut self) -> &mut Self {
235        self.if_not_exists.replace(true);
236        self
237    }
238}
239
240impl Parse for TaggedCreateRoleStatement {
241    type Output = Self;
242    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
243        s.parse::<(CREATE, ROLE)>()?;
244        let mut res = TaggedCreateRoleStatementBuilder::default();
245        res.set_if_not_exists(s.parse::<Option<(IF, NOT, EXISTS)>>()?.is_some())
246            .name(s.parse()?);
247        match s.parse_from::<If<WITH, Tag<List<RoleOpt, AND>>>>()? {
248            Some(Tag::Value(o)) => {
249                let mut opts = BTreeSet::new();
250                for opt in o {
251                    if opts.contains(&opt) {
252                        anyhow::bail!("Duplicate option: {}", opt);
253                    } else {
254                        opts.insert(opt);
255                    }
256                }
257                res.options(Tag::Value(opts));
258            }
259            Some(Tag::Tag(t)) => {
260                res.options(Tag::Tag(t));
261            }
262            _ => (),
263        }
264        s.parse::<Option<Semicolon>>()?;
265        Ok(res
266            .build()
267            .map_err(|e| anyhow::anyhow!("Invalid CREATE ROLE statement: {}", e))?)
268    }
269}
270
271impl Display for CreateRoleStatement {
272    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
273        write!(
274            f,
275            "CREATE ROLE{} {}{}",
276            if self.if_not_exists { "IF NOT EXISTS" } else { "" },
277            self.name,
278            if let Some(ref opts) = self.options {
279                if !opts.is_empty() {
280                    format!(
281                        " WITH {}",
282                        opts.iter().map(|i| i.to_string()).collect::<Vec<_>>().join(" AND ")
283                    )
284                } else {
285                    String::new()
286                }
287            } else {
288                String::new()
289            }
290        )
291    }
292}
293
294impl RoleOptBuilderExt for CreateRoleStatementBuilder {
295    fn role_opts(&mut self) -> &mut Option<BTreeSet<RoleOpt>> {
296        match self.options {
297            Some(ref mut opts) => opts,
298            None => {
299                self.options = Some(Some(BTreeSet::new()));
300                self.options.as_mut().unwrap()
301            }
302        }
303    }
304}
305
306#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
307#[builder(build_fn(validate = "Self::validate"))]
308#[parse_via(TaggedAlterRoleStatement)]
309pub struct AlterRoleStatement {
310    #[builder(setter(into))]
311    pub name: Name,
312    pub options: BTreeSet<RoleOpt>,
313}
314
315impl TryFrom<TaggedAlterRoleStatement> for AlterRoleStatement {
316    type Error = anyhow::Error;
317    fn try_from(value: TaggedAlterRoleStatement) -> Result<Self, Self::Error> {
318        Ok(Self {
319            name: value.name.into_value()?,
320            options: value.options.into_value()?,
321        })
322    }
323}
324
325#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
326#[builder(build_fn(validate = "Self::validate"))]
327#[tokenize_as(AlterRoleStatement)]
328pub struct TaggedAlterRoleStatement {
329    pub name: Tag<Name>,
330    pub options: Tag<BTreeSet<RoleOpt>>,
331}
332
333impl AlterRoleStatementBuilder {
334    fn validate(&self) -> Result<(), String> {
335        if self.options.as_ref().map(|s| s.is_empty()).unwrap_or(false) {
336            return Err("Role options cannot be empty".to_string());
337        }
338        Ok(())
339    }
340}
341
342impl TaggedAlterRoleStatementBuilder {
343    fn validate(&self) -> Result<(), String> {
344        if self
345            .options
346            .as_ref()
347            .map(|s| match s {
348                Tag::Value(v) => v.is_empty(),
349                _ => false,
350            })
351            .unwrap_or(false)
352        {
353            return Err("Role options cannot be empty".to_string());
354        }
355        Ok(())
356    }
357}
358
359impl Parse for TaggedAlterRoleStatement {
360    type Output = Self;
361    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
362        s.parse::<(ALTER, ROLE)>()?;
363        let mut res = TaggedAlterRoleStatementBuilder::default();
364        res.name(s.parse()?);
365        let o = s.parse_from::<(WITH, Tag<List<RoleOpt, AND>>)>()?.1;
366        match o {
367            Tag::Value(o) => {
368                let mut opts = BTreeSet::new();
369                for opt in o {
370                    if opts.contains(&opt) {
371                        anyhow::bail!("Duplicate option: {}", opt);
372                    } else {
373                        opts.insert(opt);
374                    }
375                }
376                res.options(Tag::Value(opts));
377            }
378            Tag::Tag(t) => {
379                res.options(Tag::Tag(t));
380            }
381        }
382
383        s.parse::<Option<Semicolon>>()?;
384        Ok(res
385            .build()
386            .map_err(|e| anyhow::anyhow!("Invalid ALTER ROLE statement: {}", e))?)
387    }
388}
389
390impl Display for AlterRoleStatement {
391    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
392        write!(
393            f,
394            "ALTER ROLE {} WITH {}",
395            self.name,
396            self.options
397                .iter()
398                .map(|i| i.to_string())
399                .collect::<Vec<_>>()
400                .join(" AND ")
401        )
402    }
403}
404
405impl RoleOptBuilderExt for AlterRoleStatementBuilder {
406    fn role_opts(&mut self) -> &mut Option<BTreeSet<RoleOpt>> {
407        &mut self.options
408    }
409}
410
411#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
412#[parse_via(TaggedDropRoleStatement)]
413pub struct DropRoleStatement {
414    #[builder(setter(name = "set_if_exists"), default)]
415    pub if_exists: bool,
416    #[builder(setter(into))]
417    pub name: Name,
418}
419
420impl TryFrom<TaggedDropRoleStatement> for DropRoleStatement {
421    type Error = anyhow::Error;
422    fn try_from(value: TaggedDropRoleStatement) -> Result<Self, Self::Error> {
423        Ok(Self {
424            if_exists: value.if_exists,
425            name: value.name.into_value()?,
426        })
427    }
428}
429
430#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
431#[tokenize_as(DropRoleStatement)]
432pub struct TaggedDropRoleStatement {
433    #[builder(setter(name = "set_if_exists"), default)]
434    pub if_exists: bool,
435    pub name: Tag<Name>,
436}
437
438impl DropRoleStatementBuilder {
439    /// Set IF EXISTS on the statement.
440    /// To undo this, use `set_if_exists(false)`.
441    pub fn if_exists(&mut self) -> &mut Self {
442        self.if_exists.replace(true);
443        self
444    }
445}
446
447impl Parse for TaggedDropRoleStatement {
448    type Output = Self;
449    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
450        s.parse::<(DROP, ROLE)>()?;
451        let mut res = TaggedDropRoleStatementBuilder::default();
452        loop {
453            if s.remaining() == 0 || s.parse::<Option<Semicolon>>()?.is_some() {
454                break;
455            }
456            if s.parse::<Option<(IF, EXISTS)>>()?.is_some() {
457                res.set_if_exists(true);
458            } else if let Some(n) = s.parse()? {
459                res.name(n);
460            } else {
461                return Ok(res
462                    .build()
463                    .map_err(|_| anyhow::anyhow!("Invalid tokens in DROP ROLE statement: {}", s.info()))?);
464            }
465        }
466        Ok(res
467            .build()
468            .map_err(|e| anyhow::anyhow!("Invalid DROP ROLE statement: {}", e))?)
469    }
470}
471
472impl Display for DropRoleStatement {
473    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
474        write!(
475            f,
476            "DROP ROLE{} {}",
477            if self.if_exists { " IF EXISTS" } else { "" },
478            self.name
479        )
480    }
481}
482
483#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
484#[builder(setter(into))]
485#[parse_via(TaggedGrantRoleStatement)]
486pub struct GrantRoleStatement {
487    pub name: Name,
488    pub to: Name,
489}
490
491impl TryFrom<TaggedGrantRoleStatement> for GrantRoleStatement {
492    type Error = anyhow::Error;
493    fn try_from(value: TaggedGrantRoleStatement) -> Result<Self, Self::Error> {
494        Ok(Self {
495            name: value.name.into_value()?,
496            to: value.to.into_value()?,
497        })
498    }
499}
500
501#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
502#[tokenize_as(GrantRoleStatement)]
503pub struct TaggedGrantRoleStatement {
504    pub name: Tag<Name>,
505    pub to: Tag<Name>,
506}
507
508impl Parse for TaggedGrantRoleStatement {
509    type Output = Self;
510    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
511        s.parse::<GRANT>()?;
512        let mut res = TaggedGrantRoleStatementBuilder::default();
513        res.name(s.parse()?);
514        s.parse::<TO>()?;
515        res.to(s.parse()?);
516        s.parse::<Option<Semicolon>>()?;
517        Ok(res
518            .build()
519            .map_err(|e| anyhow::anyhow!("Invalid GRANT ROLE statement: {}", e))?)
520    }
521}
522
523impl Display for GrantRoleStatement {
524    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
525        write!(f, "GRANT {} TO {}", self.name, self.to)
526    }
527}
528
529#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
530#[builder(setter(into))]
531#[parse_via(TaggedRevokeRoleStatement)]
532pub struct RevokeRoleStatement {
533    pub name: Name,
534    pub from: Name,
535}
536
537impl TryFrom<TaggedRevokeRoleStatement> for RevokeRoleStatement {
538    type Error = anyhow::Error;
539    fn try_from(value: TaggedRevokeRoleStatement) -> Result<Self, Self::Error> {
540        Ok(Self {
541            name: value.name.into_value()?,
542            from: value.from.into_value()?,
543        })
544    }
545}
546
547#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
548#[tokenize_as(RevokeRoleStatement)]
549pub struct TaggedRevokeRoleStatement {
550    pub name: Tag<Name>,
551    pub from: Tag<Name>,
552}
553
554impl Parse for TaggedRevokeRoleStatement {
555    type Output = Self;
556    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
557        s.parse::<REVOKE>()?;
558        let mut res = TaggedRevokeRoleStatementBuilder::default();
559        res.name(s.parse()?);
560        s.parse::<FROM>()?;
561        res.from(s.parse()?);
562        s.parse::<Option<Semicolon>>()?;
563        Ok(res
564            .build()
565            .map_err(|e| anyhow::anyhow!("Invalid REVOKE ROLE statement: {}", e))?)
566    }
567}
568
569impl Display for RevokeRoleStatement {
570    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
571        write!(f, "REVOKE {} FROM {}", self.name, self.from)
572    }
573}
574
575#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
576#[builder(setter(strip_option))]
577#[parse_via(TaggedListRolesStatement)]
578pub struct ListRolesStatement {
579    #[builder(setter(into), default)]
580    pub of: Option<Name>,
581    #[builder(setter(name = "set_no_recursive"), default)]
582    pub no_recursive: bool,
583}
584
585impl TryFrom<TaggedListRolesStatement> for ListRolesStatement {
586    type Error = anyhow::Error;
587    fn try_from(value: TaggedListRolesStatement) -> Result<Self, Self::Error> {
588        Ok(Self {
589            of: value.of.map(|v| v.into_value()).transpose()?,
590            no_recursive: value.no_recursive,
591        })
592    }
593}
594
595#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
596#[builder(setter(strip_option))]
597#[tokenize_as(ListRolesStatement)]
598pub struct TaggedListRolesStatement {
599    #[builder(default)]
600    pub of: Option<Tag<Name>>,
601    #[builder(setter(name = "set_no_recursive"), default)]
602    pub no_recursive: bool,
603}
604
605impl ListRolesStatementBuilder {
606    /// Set NO RECURSIVE on the statement.
607    /// To undo this, use `set_no_recursive(false)`.
608    pub fn no_recursive(&mut self) -> &mut Self {
609        self.no_recursive.replace(true);
610        self
611    }
612}
613
614impl Parse for TaggedListRolesStatement {
615    type Output = Self;
616    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
617        s.parse::<(LIST, ROLES)>()?;
618        let mut res = TaggedListRolesStatementBuilder::default();
619        if let Some(n) = s.parse_from::<If<OF, Tag<Name>>>()? {
620            res.of(n);
621        }
622        res.set_no_recursive(s.parse::<Option<NORECURSIVE>>()?.is_some());
623        s.parse::<Option<Semicolon>>()?;
624        Ok(res
625            .build()
626            .map_err(|e| anyhow::anyhow!("Invalid LIST ROLES statement: {}", e))?)
627    }
628}
629
630impl Display for ListRolesStatement {
631    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
632        write!(
633            f,
634            "LIST ROLES{}{}",
635            if let Some(n) = &self.of {
636                format!(" OF {}", n)
637            } else {
638                String::new()
639            },
640            if self.no_recursive { " NORECURSIVE" } else { "" },
641        )
642    }
643}
644
645#[derive(ParseFromStr, Clone, Debug, ToTokens, PartialEq, Eq)]
646pub enum Permission {
647    Create,
648    Alter,
649    Drop,
650    Select,
651    Modify,
652    Authorize,
653    Describe,
654    Execute,
655}
656
657impl Parse for Permission {
658    type Output = Self;
659    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
660        Ok(match s.parse::<(ReservedKeyword, Option<PERMISSION>)>()?.0 {
661            ReservedKeyword::CREATE => Permission::Create,
662            ReservedKeyword::ALTER => Permission::Alter,
663            ReservedKeyword::DROP => Permission::Drop,
664            ReservedKeyword::SELECT => Permission::Select,
665            ReservedKeyword::MODIFY => Permission::Modify,
666            ReservedKeyword::AUTHORIZE => Permission::Authorize,
667            ReservedKeyword::DESCRIBE => Permission::Describe,
668            ReservedKeyword::EXECUTE => Permission::Execute,
669            p @ _ => anyhow::bail!("Expected permission, found {}", p),
670        })
671    }
672}
673
674impl Display for Permission {
675    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
676        write!(
677            f,
678            "{}",
679            match self {
680                Permission::Create => "CREATE",
681                Permission::Alter => "ALTER",
682                Permission::Drop => "DROP",
683                Permission::Select => "SELECT",
684                Permission::Modify => "MODIFY",
685                Permission::Authorize => "AUTHORIZE",
686                Permission::Describe => "DESCRIBE",
687                Permission::Execute => "EXECUTE",
688            }
689        )
690    }
691}
692
693#[derive(ParseFromStr, Clone, Debug, ToTokens, PartialEq, Eq)]
694pub enum PermissionKind {
695    All,
696    One(Permission),
697}
698
699impl Parse for PermissionKind {
700    type Output = Self;
701    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
702        Ok(if s.parse::<Option<(ALL, Option<PERMISSIONS>)>>()?.is_some() {
703            PermissionKind::All
704        } else {
705            PermissionKind::One(s.parse()?)
706        })
707    }
708}
709
710impl Display for PermissionKind {
711    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
712        match self {
713            PermissionKind::All => write!(f, "ALL PERMISSIONS"),
714            PermissionKind::One(p) => write!(f, "{} PERMISSION", p),
715        }
716    }
717}
718
719impl From<Permission> for PermissionKind {
720    fn from(p: Permission) -> Self {
721        PermissionKind::One(p)
722    }
723}
724
725#[derive(ParseFromStr, Clone, Debug, ToTokens, PartialEq, Eq)]
726pub enum Resource {
727    AllKeyspaces,
728    Keyspace(Name),
729    Table(KeyspaceQualifiedName),
730    AllRoles,
731    Role(Name),
732    AllFunctions { keyspace: Option<Name> },
733    Function(FunctionReference),
734    AllMBeans,
735    MBean(LitStr),
736}
737
738impl Resource {
739    pub fn all_keyspaces() -> Self {
740        Resource::AllKeyspaces
741    }
742
743    pub fn keyspace(name: impl Into<Name>) -> Self {
744        Resource::Keyspace(name.into())
745    }
746
747    pub fn table(name: impl Into<KeyspaceQualifiedName>) -> Self {
748        Resource::Table(name.into())
749    }
750
751    pub fn all_roles() -> Self {
752        Resource::AllRoles
753    }
754
755    pub fn role(name: impl Into<Name>) -> Self {
756        Resource::Role(name.into())
757    }
758
759    pub fn all_functions() -> Self {
760        Resource::AllFunctions { keyspace: None }
761    }
762
763    pub fn all_functions_in_keyspace(keyspace: impl Into<Name>) -> Self {
764        Resource::AllFunctions {
765            keyspace: Some(keyspace.into()),
766        }
767    }
768
769    pub fn function(name: impl Into<FunctionReference>) -> Self {
770        Resource::Function(name.into())
771    }
772
773    pub fn all_mbeans() -> Self {
774        Resource::AllMBeans
775    }
776
777    pub fn mbean(name: impl Into<LitStr>) -> Self {
778        Resource::MBean(name.into())
779    }
780}
781
782impl Parse for Resource {
783    type Output = Self;
784    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
785        Ok(if s.parse::<Option<(ALL, KEYSPACES)>>()?.is_some() {
786            Self::AllKeyspaces
787        } else if s.parse::<Option<KEYSPACE>>()?.is_some() {
788            Self::Keyspace(s.parse()?)
789        } else if s.parse::<Option<(ALL, ROLES)>>()?.is_some() {
790            Self::AllRoles
791        } else if s.parse::<Option<ROLE>>()?.is_some() {
792            Self::Role(s.parse()?)
793        } else if s.parse::<Option<(ALL, FUNCTIONS)>>()?.is_some() {
794            Self::AllFunctions {
795                keyspace: s.parse::<Option<(IN, KEYSPACE, _)>>()?.map(|i| i.2),
796            }
797        } else if s.parse::<Option<FUNCTION>>()?.is_some() {
798            Self::Function(s.parse()?)
799        } else if s.parse::<Option<(ALL, MBEANS)>>()?.is_some() {
800            Self::AllMBeans
801        } else if s.parse::<Option<MBEAN>>()?.is_some() {
802            Self::MBean(s.parse()?)
803        } else if s.parse::<Option<MBEANS>>()?.is_some() {
804            Self::MBean(s.parse()?)
805        } else if let Some(t) = s.parse_from::<If<TABLE, KeyspaceQualifiedName>>()? {
806            Self::Table(t)
807        } else if let Some(name) = s.parse::<Option<KeyspaceQualifiedName>>()? {
808            Self::Table(name)
809        } else {
810            anyhow::bail!("Expected resource, found {}", s.info())
811        })
812    }
813}
814
815impl Display for Resource {
816    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
817        match self {
818            Resource::AllKeyspaces => write!(f, "ALL KEYSPACES"),
819            Resource::Keyspace(n) => write!(f, "KEYSPACE {}", n),
820            Resource::Table(n) => write!(f, "TABLE {}", n),
821            Resource::AllRoles => write!(f, "ALL ROLES"),
822            Resource::Role(n) => write!(f, "ROLE {}", n),
823            Resource::AllFunctions { keyspace } => {
824                write!(f, "ALL FUNCTIONS")?;
825                if let Some(k) = keyspace {
826                    write!(f, " IN KEYSPACE {}", k)?;
827                }
828                Ok(())
829            }
830            Resource::Function(r) => write!(f, "FUNCTION {}", r),
831            Resource::AllMBeans => write!(f, "ALL MBEANS"),
832            Resource::MBean(n) => write!(f, "MBEAN {}", n),
833        }
834    }
835}
836
837#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
838#[parse_via(TaggedPermissionStatement)]
839pub enum PermissionStatement {
840    Grant(GrantPermissionStatement),
841    Revoke(RevokePermissionStatement),
842    List(ListPermissionsStatement),
843}
844
845impl TryFrom<TaggedPermissionStatement> for PermissionStatement {
846    type Error = anyhow::Error;
847    fn try_from(value: TaggedPermissionStatement) -> Result<Self, Self::Error> {
848        Ok(match value {
849            TaggedPermissionStatement::Grant(s) => PermissionStatement::Grant(s.try_into()?),
850            TaggedPermissionStatement::Revoke(s) => PermissionStatement::Revoke(s.try_into()?),
851            TaggedPermissionStatement::List(s) => PermissionStatement::List(s.try_into()?),
852        })
853    }
854}
855
856#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
857#[tokenize_as(PermissionStatement)]
858pub enum TaggedPermissionStatement {
859    Grant(TaggedGrantPermissionStatement),
860    Revoke(TaggedRevokePermissionStatement),
861    List(TaggedListPermissionsStatement),
862}
863
864impl Parse for TaggedPermissionStatement {
865    type Output = Self;
866    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
867        Ok(if s.check::<GRANT>() {
868            Self::Grant(s.parse()?)
869        } else if s.check::<REVOKE>() {
870            Self::Revoke(s.parse()?)
871        } else if s.check::<LIST>() {
872            Self::List(s.parse()?)
873        } else {
874            anyhow::bail!("Expected a permission statement, found {}", s.info())
875        })
876    }
877}
878
879impl Display for PermissionStatement {
880    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
881        match self {
882            Self::Grant(stmt) => stmt.fmt(f),
883            Self::Revoke(stmt) => stmt.fmt(f),
884            Self::List(stmt) => stmt.fmt(f),
885        }
886    }
887}
888
889#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
890#[builder(setter(into))]
891#[parse_via(TaggedGrantPermissionStatement)]
892pub struct GrantPermissionStatement {
893    pub permission: PermissionKind,
894    pub resource: Resource,
895    pub to: Name,
896}
897
898impl TryFrom<TaggedGrantPermissionStatement> for GrantPermissionStatement {
899    type Error = anyhow::Error;
900    fn try_from(value: TaggedGrantPermissionStatement) -> Result<Self, Self::Error> {
901        Ok(Self {
902            permission: value.permission.into_value()?,
903            resource: value.resource.into_value()?,
904            to: value.to.into_value()?,
905        })
906    }
907}
908
909#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
910#[tokenize_as(GrantPermissionStatement)]
911pub struct TaggedGrantPermissionStatement {
912    pub permission: Tag<PermissionKind>,
913    pub resource: Tag<Resource>,
914    pub to: Tag<Name>,
915}
916
917impl Parse for TaggedGrantPermissionStatement {
918    type Output = Self;
919    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
920        s.parse::<GRANT>()?;
921        let mut res = TaggedGrantPermissionStatementBuilder::default();
922        res.permission(s.parse()?);
923        s.parse::<ON>()?;
924        res.resource(s.parse()?);
925        s.parse::<TO>()?;
926        res.to(s.parse()?);
927        s.parse::<Option<Semicolon>>()?;
928        Ok(res
929            .build()
930            .map_err(|e| anyhow::anyhow!("Invalid GRANT PERMISSION statement: {}", e))?)
931    }
932}
933
934impl Display for GrantPermissionStatement {
935    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
936        write!(f, "GRANT {} ON {} TO {}", self.permission, self.resource, self.to)
937    }
938}
939
940#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
941#[builder(setter(into))]
942#[parse_via(TaggedRevokePermissionStatement)]
943pub struct RevokePermissionStatement {
944    pub permission: PermissionKind,
945    pub resource: Resource,
946    pub from: Name,
947}
948
949impl TryFrom<TaggedRevokePermissionStatement> for RevokePermissionStatement {
950    type Error = anyhow::Error;
951    fn try_from(value: TaggedRevokePermissionStatement) -> Result<Self, Self::Error> {
952        Ok(Self {
953            permission: value.permission.into_value()?,
954            resource: value.resource.into_value()?,
955            from: value.from.into_value()?,
956        })
957    }
958}
959
960#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
961#[tokenize_as(RevokePermissionStatement)]
962pub struct TaggedRevokePermissionStatement {
963    pub permission: Tag<PermissionKind>,
964    pub resource: Tag<Resource>,
965    pub from: Tag<Name>,
966}
967
968impl Parse for TaggedRevokePermissionStatement {
969    type Output = Self;
970    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
971        s.parse::<REVOKE>()?;
972        let mut res = TaggedRevokePermissionStatementBuilder::default();
973        res.permission(s.parse()?);
974        s.parse::<ON>()?;
975        res.resource(s.parse()?);
976        s.parse::<FROM>()?;
977        res.from(s.parse()?);
978        s.parse::<Option<Semicolon>>()?;
979        Ok(res
980            .build()
981            .map_err(|e| anyhow::anyhow!("Invalid REVOKE PERMISSION statement: {}", e))?)
982    }
983}
984
985impl Display for RevokePermissionStatement {
986    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
987        write!(f, "REVOKE {} ON {} FROM {}", self.permission, self.resource, self.from)
988    }
989}
990
991#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
992#[builder(setter(strip_option))]
993#[parse_via(TaggedListPermissionsStatement)]
994pub struct ListPermissionsStatement {
995    #[builder(setter(into))]
996    pub permission: PermissionKind,
997    #[builder(setter(into), default)]
998    pub resource: Option<Resource>,
999    #[builder(setter(into), default)]
1000    pub of: Option<Name>,
1001    #[builder(setter(name = "set_no_recursive"), default)]
1002    pub no_recursive: bool,
1003}
1004
1005impl TryFrom<TaggedListPermissionsStatement> for ListPermissionsStatement {
1006    type Error = anyhow::Error;
1007    fn try_from(value: TaggedListPermissionsStatement) -> Result<Self, Self::Error> {
1008        Ok(Self {
1009            permission: value.permission.into_value()?,
1010            resource: value.resource.map(|v| v.into_value()).transpose()?,
1011            of: value.of.map(|v| v.into_value()).transpose()?,
1012            no_recursive: value.no_recursive,
1013        })
1014    }
1015}
1016
1017#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1018#[builder(setter(strip_option))]
1019#[tokenize_as(ListPermissionsStatement)]
1020pub struct TaggedListPermissionsStatement {
1021    pub permission: Tag<PermissionKind>,
1022    #[builder(default)]
1023    pub resource: Option<Tag<Resource>>,
1024    #[builder(default)]
1025    pub of: Option<Tag<Name>>,
1026    #[builder(setter(name = "set_no_recursive"), default)]
1027    pub no_recursive: bool,
1028}
1029
1030impl ListPermissionsStatementBuilder {
1031    /// Set NO RECURSIVE on the statement.
1032    /// To undo this, use `set_no_recursive(false)`.
1033    pub fn no_recursive(&mut self) -> &mut Self {
1034        self.no_recursive.replace(true);
1035        self
1036    }
1037}
1038
1039impl Parse for TaggedListPermissionsStatement {
1040    type Output = Self;
1041    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1042        s.parse::<LIST>()?;
1043        let mut res = TaggedListPermissionsStatementBuilder::default();
1044        res.permission(s.parse()?);
1045        loop {
1046            if s.remaining() == 0 || s.parse::<Option<Semicolon>>()?.is_some() {
1047                break;
1048            }
1049            if let Some(resource) = s.parse_from::<If<ON, Tag<Resource>>>()? {
1050                if res.resource.is_some() {
1051                    anyhow::bail!("Duplicate ON RESOURCE clause!");
1052                }
1053                res.resource(resource);
1054            } else if let Some(role) = s.parse_from::<If<OF, Tag<Name>>>()? {
1055                if res.of.is_some() {
1056                    anyhow::bail!("Duplicate OF ROLE clause!");
1057                }
1058                res.of(role)
1059                    .set_no_recursive(s.parse::<Option<NORECURSIVE>>()?.is_some());
1060            } else {
1061                return Ok(res
1062                    .build()
1063                    .map_err(|_| anyhow::anyhow!("Invalid tokens in LIST PERMISSION statement: {}", s.info()))?);
1064            }
1065        }
1066        Ok(res
1067            .build()
1068            .map_err(|e| anyhow::anyhow!("Invalid LIST PERMISSION statement: {}", e))?)
1069    }
1070}
1071
1072impl Display for ListPermissionsStatement {
1073    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1074        write!(
1075            f,
1076            "LIST {}{}",
1077            self.permission,
1078            if let Some(resource) = &self.resource {
1079                format!(" ON {}", resource)
1080            } else {
1081                String::new()
1082            }
1083        )?;
1084        if let Some(role) = &self.of {
1085            write!(f, " OF {}", role)?;
1086            if self.no_recursive {
1087                write!(f, " NORECURSIVE")?;
1088            }
1089        }
1090        Ok(())
1091    }
1092}
1093
1094#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
1095#[parse_via(TaggedUserStatement)]
1096pub enum UserStatement {
1097    Create(CreateUserStatement),
1098    Alter(AlterUserStatement),
1099    Drop(DropUserStatement),
1100    List(ListUsersStatement),
1101}
1102
1103impl TryFrom<TaggedUserStatement> for UserStatement {
1104    type Error = anyhow::Error;
1105    fn try_from(value: TaggedUserStatement) -> Result<Self, Self::Error> {
1106        Ok(match value {
1107            TaggedUserStatement::Create(v) => Self::Create(v.try_into()?),
1108            TaggedUserStatement::Alter(v) => Self::Alter(v.try_into()?),
1109            TaggedUserStatement::Drop(v) => Self::Drop(v.try_into()?),
1110            TaggedUserStatement::List(v) => Self::List(v.try_into()?),
1111        })
1112    }
1113}
1114
1115#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
1116#[tokenize_as(UserStatement)]
1117pub enum TaggedUserStatement {
1118    Create(TaggedCreateUserStatement),
1119    Alter(TaggedAlterUserStatement),
1120    Drop(TaggedDropUserStatement),
1121    List(ListUsersStatement),
1122}
1123
1124impl Parse for TaggedUserStatement {
1125    type Output = Self;
1126    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1127        Ok(if s.check::<CREATE>() {
1128            Self::Create(s.parse()?)
1129        } else if s.check::<ALTER>() {
1130            Self::Alter(s.parse()?)
1131        } else if s.check::<DROP>() {
1132            Self::Drop(s.parse()?)
1133        } else if s.check::<LIST>() {
1134            Self::List(s.parse()?)
1135        } else {
1136            anyhow::bail!("Expected a user statement, found {}", s.info())
1137        })
1138    }
1139}
1140
1141impl Display for UserStatement {
1142    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1143        match self {
1144            Self::Create(stmt) => stmt.fmt(f),
1145            Self::Alter(stmt) => stmt.fmt(f),
1146            Self::Drop(stmt) => stmt.fmt(f),
1147            Self::List(stmt) => stmt.fmt(f),
1148        }
1149    }
1150}
1151
1152#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1153#[builder(setter(strip_option))]
1154#[parse_via(TaggedCreateUserStatement)]
1155pub struct CreateUserStatement {
1156    #[builder(setter(name = "set_if_not_exists"), default)]
1157    pub if_not_exists: bool,
1158    #[builder(setter(into))]
1159    pub name: Name,
1160    #[builder(setter(into), default)]
1161    pub with_password: Option<LitStr>,
1162    #[builder(default)]
1163    pub superuser: Option<bool>,
1164}
1165
1166impl TryFrom<TaggedCreateUserStatement> for CreateUserStatement {
1167    type Error = anyhow::Error;
1168    fn try_from(value: TaggedCreateUserStatement) -> Result<Self, Self::Error> {
1169        Ok(Self {
1170            if_not_exists: value.if_not_exists,
1171            name: value.name.into_value()?,
1172            with_password: value.with_password.map(|v| v.into_value()).transpose()?,
1173            superuser: value.superuser,
1174        })
1175    }
1176}
1177
1178#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1179#[builder(setter(strip_option))]
1180#[tokenize_as(CreateUserStatement)]
1181pub struct TaggedCreateUserStatement {
1182    #[builder(setter(name = "set_if_not_exists"), default)]
1183    pub if_not_exists: bool,
1184    pub name: Tag<Name>,
1185    #[builder(default)]
1186    pub with_password: Option<Tag<LitStr>>,
1187    #[builder(default)]
1188    pub superuser: Option<bool>,
1189}
1190
1191impl CreateUserStatementBuilder {
1192    /// Set IF NOT EXISTS on the statement.
1193    /// To undo this, use `set_if_not_exists(false)`.
1194    pub fn if_not_exists(&mut self) -> &mut Self {
1195        self.if_not_exists.replace(true);
1196        self
1197    }
1198}
1199
1200impl Parse for TaggedCreateUserStatement {
1201    type Output = Self;
1202    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1203        s.parse::<(CREATE, USER)>()?;
1204        let mut res = TaggedCreateUserStatementBuilder::default();
1205        res.set_if_not_exists(s.parse::<Option<(IF, NOT, EXISTS)>>()?.is_some())
1206            .name(s.parse()?);
1207        loop {
1208            if s.remaining() == 0 || s.parse::<Option<Semicolon>>()?.is_some() {
1209                break;
1210            }
1211            if let Some(password) = s.parse_from::<If<(WITH, PASSWORD), Tag<LitStr>>>()? {
1212                if res.with_password.is_some() {
1213                    anyhow::bail!("Duplicate WITH PASSWORD clause!");
1214                }
1215                res.with_password(password);
1216            } else if s.parse::<Option<SUPERUSER>>()?.is_some() {
1217                if res.superuser.is_some() {
1218                    anyhow::bail!("Duplicate SUPERUSER option definition!");
1219                }
1220                res.superuser(true);
1221            } else if s.parse::<Option<NOSUPERUSER>>()?.is_some() {
1222                if res.superuser.is_some() {
1223                    anyhow::bail!("Duplicate SUPERUSER option definition!");
1224                }
1225                res.superuser(false);
1226            } else {
1227                return Ok(res
1228                    .build()
1229                    .map_err(|_| anyhow::anyhow!("Invalid tokens in CREATE USER statement: {}", s.info()))?);
1230            }
1231        }
1232        Ok(res
1233            .build()
1234            .map_err(|e| anyhow::anyhow!("Invalid CREATE USER statement: {}", e))?)
1235    }
1236}
1237
1238impl Display for CreateUserStatement {
1239    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1240        write!(
1241            f,
1242            "CREATE USER{} {}",
1243            if self.if_not_exists { " IF NOT EXISTS" } else { "" },
1244            self.name
1245        )?;
1246        if let Some(password) = &self.with_password {
1247            write!(f, " WITH PASSWORD {}", password)?;
1248        }
1249        if let Some(superuser) = self.superuser {
1250            write!(f, " {}", if superuser { "SUPERUSER" } else { "NOSUPERUSER" })?;
1251        }
1252        Ok(())
1253    }
1254}
1255
1256#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1257#[builder(setter(strip_option))]
1258#[parse_via(TaggedAlterUserStatement)]
1259pub struct AlterUserStatement {
1260    #[builder(setter(into))]
1261    pub name: Name,
1262    #[builder(setter(into), default)]
1263    pub with_password: Option<LitStr>,
1264    #[builder(default)]
1265    pub superuser: Option<bool>,
1266}
1267
1268impl TryFrom<TaggedAlterUserStatement> for AlterUserStatement {
1269    type Error = anyhow::Error;
1270    fn try_from(value: TaggedAlterUserStatement) -> Result<Self, Self::Error> {
1271        Ok(Self {
1272            name: value.name.into_value()?,
1273            with_password: value.with_password.map(|v| v.into_value()).transpose()?,
1274            superuser: value.superuser,
1275        })
1276    }
1277}
1278
1279#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1280#[builder(setter(strip_option))]
1281#[tokenize_as(AlterUserStatement)]
1282pub struct TaggedAlterUserStatement {
1283    pub name: Tag<Name>,
1284    #[builder(default)]
1285    pub with_password: Option<Tag<LitStr>>,
1286    #[builder(default)]
1287    pub superuser: Option<bool>,
1288}
1289
1290impl Parse for TaggedAlterUserStatement {
1291    type Output = Self;
1292    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1293        s.parse::<(ALTER, USER)>()?;
1294        let mut res = TaggedAlterUserStatementBuilder::default();
1295        res.name(s.parse()?);
1296        loop {
1297            if s.remaining() == 0 || s.parse::<Option<Semicolon>>()?.is_some() {
1298                break;
1299            }
1300            if let Some(password) = s.parse_from::<If<(WITH, PASSWORD), Tag<LitStr>>>()? {
1301                if res.with_password.is_some() {
1302                    anyhow::bail!("Duplicate WITH PASSWORD clause!");
1303                }
1304                res.with_password(password);
1305            } else if s.parse::<Option<SUPERUSER>>()?.is_some() {
1306                if res.superuser.is_some() {
1307                    anyhow::bail!("Duplicate SUPERUSER option definition!");
1308                }
1309                res.superuser(true);
1310            } else if s.parse::<Option<NOSUPERUSER>>()?.is_some() {
1311                if res.superuser.is_some() {
1312                    anyhow::bail!("Duplicate SUPERUSER option definition!");
1313                }
1314                res.superuser(false);
1315            } else {
1316                return Ok(res
1317                    .build()
1318                    .map_err(|_| anyhow::anyhow!("Invalid tokens in ALTER USER statement: {}", s.info()))?);
1319            }
1320        }
1321        Ok(res
1322            .build()
1323            .map_err(|e| anyhow::anyhow!("Invalid ALTER USER statement: {}", e))?)
1324    }
1325}
1326
1327impl Display for AlterUserStatement {
1328    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1329        write!(f, "ALTER USER {}", self.name)?;
1330        if let Some(password) = &self.with_password {
1331            write!(f, " WITH PASSWORD {}", password)?;
1332        }
1333        if let Some(superuser) = self.superuser {
1334            write!(f, " {}", if superuser { "SUPERUSER" } else { "NOSUPERUSER" })?;
1335        }
1336        Ok(())
1337    }
1338}
1339
1340#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1341#[parse_via(TaggedDropUserStatement)]
1342pub struct DropUserStatement {
1343    #[builder(setter(name = "set_if_exists"), default)]
1344    pub if_exists: bool,
1345    #[builder(setter(into))]
1346    pub name: Name,
1347}
1348
1349impl TryFrom<TaggedDropUserStatement> for DropUserStatement {
1350    type Error = anyhow::Error;
1351    fn try_from(value: TaggedDropUserStatement) -> Result<Self, Self::Error> {
1352        Ok(Self {
1353            if_exists: value.if_exists,
1354            name: value.name.into_value()?,
1355        })
1356    }
1357}
1358
1359#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1360#[tokenize_as(DropUserStatement)]
1361pub struct TaggedDropUserStatement {
1362    #[builder(setter(name = "set_if_exists"), default)]
1363    pub if_exists: bool,
1364    pub name: Tag<Name>,
1365}
1366
1367impl DropUserStatementBuilder {
1368    /// Set IF EXISTS on the statement.
1369    /// To undo this, use `set_if_exists(false)`.
1370    pub fn if_exists(&mut self) -> &mut Self {
1371        self.if_exists.replace(true);
1372        self
1373    }
1374}
1375
1376impl Parse for TaggedDropUserStatement {
1377    type Output = Self;
1378    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1379        s.parse::<(DROP, USER)>()?;
1380        let mut res = TaggedDropUserStatementBuilder::default();
1381        res.set_if_exists(s.parse::<Option<(IF, EXISTS)>>()?.is_some())
1382            .name(s.parse()?);
1383        s.parse::<Option<Semicolon>>()?;
1384        Ok(res
1385            .build()
1386            .map_err(|e| anyhow::anyhow!("Invalid DROP USER statement: {}", e))?)
1387    }
1388}
1389
1390impl Display for DropUserStatement {
1391    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1392        write!(
1393            f,
1394            "DROP USER{} {}",
1395            if self.if_exists { " IF EXISTS" } else { "" },
1396            self.name
1397        )
1398    }
1399}
1400
1401#[derive(ParseFromStr, Copy, Clone, Debug, ToTokens, PartialEq, Eq)]
1402pub struct ListUsersStatement;
1403
1404impl Parse for ListUsersStatement {
1405    type Output = Self;
1406    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1407        s.parse::<(LIST, USERS, Option<Semicolon>)>()?;
1408        Ok(ListUsersStatement)
1409    }
1410}
1411
1412impl Display for ListUsersStatement {
1413    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1414        write!(f, "LIST USERS")
1415    }
1416}
1417
1418#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
1419#[parse_via(TaggedUserDefinedTypeStatement)]
1420pub enum UserDefinedTypeStatement {
1421    Create(CreateUserDefinedTypeStatement),
1422    Alter(AlterUserDefinedTypeStatement),
1423    Drop(DropUserDefinedTypeStatement),
1424}
1425
1426impl TryFrom<TaggedUserDefinedTypeStatement> for UserDefinedTypeStatement {
1427    type Error = anyhow::Error;
1428    fn try_from(value: TaggedUserDefinedTypeStatement) -> Result<Self, Self::Error> {
1429        Ok(match value {
1430            TaggedUserDefinedTypeStatement::Create(s) => UserDefinedTypeStatement::Create(s.try_into()?),
1431            TaggedUserDefinedTypeStatement::Alter(s) => UserDefinedTypeStatement::Alter(s.try_into()?),
1432            TaggedUserDefinedTypeStatement::Drop(s) => UserDefinedTypeStatement::Drop(s.try_into()?),
1433        })
1434    }
1435}
1436
1437#[derive(ParseFromStr, Clone, Debug, TryInto, From, ToTokens, PartialEq, Eq)]
1438#[tokenize_as(UserDefinedTypeStatement)]
1439pub enum TaggedUserDefinedTypeStatement {
1440    Create(TaggedCreateUserDefinedTypeStatement),
1441    Alter(TaggedAlterUserDefinedTypeStatement),
1442    Drop(TaggedDropUserDefinedTypeStatement),
1443}
1444
1445impl Parse for TaggedUserDefinedTypeStatement {
1446    type Output = Self;
1447    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1448        Ok(
1449            if let Some(stmt) = s.parse::<Option<TaggedCreateUserDefinedTypeStatement>>()? {
1450                Self::Create(stmt)
1451            } else if let Some(stmt) = s.parse::<Option<TaggedAlterUserDefinedTypeStatement>>()? {
1452                Self::Alter(stmt)
1453            } else if let Some(stmt) = s.parse::<Option<TaggedDropUserDefinedTypeStatement>>()? {
1454                Self::Drop(stmt)
1455            } else {
1456                anyhow::bail!("Expected user defined type statement, found {}", s.info())
1457            },
1458        )
1459    }
1460}
1461
1462impl Display for UserDefinedTypeStatement {
1463    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1464        match self {
1465            Self::Create(stmt) => stmt.fmt(f),
1466            Self::Alter(stmt) => stmt.fmt(f),
1467            Self::Drop(stmt) => stmt.fmt(f),
1468        }
1469    }
1470}
1471
1472#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1473#[builder(build_fn(validate = "Self::validate"))]
1474#[parse_via(TaggedCreateUserDefinedTypeStatement)]
1475pub struct CreateUserDefinedTypeStatement {
1476    #[builder(setter(name = "set_if_not_exists"), default)]
1477    pub if_not_exists: bool,
1478    #[builder(setter(into))]
1479    pub name: KeyspaceQualifiedName,
1480    pub fields: Vec<FieldDefinition>,
1481}
1482
1483impl TryFrom<TaggedCreateUserDefinedTypeStatement> for CreateUserDefinedTypeStatement {
1484    type Error = anyhow::Error;
1485    fn try_from(value: TaggedCreateUserDefinedTypeStatement) -> Result<Self, Self::Error> {
1486        Ok(Self {
1487            if_not_exists: value.if_not_exists,
1488            name: value.name.try_into()?,
1489            fields: value.fields,
1490        })
1491    }
1492}
1493
1494#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1495#[builder(build_fn(validate = "Self::validate"))]
1496#[tokenize_as(CreateUserDefinedTypeStatement)]
1497pub struct TaggedCreateUserDefinedTypeStatement {
1498    #[builder(setter(name = "set_if_not_exists"), default)]
1499    pub if_not_exists: bool,
1500    pub name: TaggedKeyspaceQualifiedName,
1501    pub fields: Vec<FieldDefinition>,
1502}
1503
1504impl CreateUserDefinedTypeStatementBuilder {
1505    /// Set IF NOT EXISTS on the statement.
1506    /// To undo this, use `set_if_not_exists(false)`.
1507    pub fn if_not_exists(&mut self) -> &mut Self {
1508        self.if_not_exists.replace(true);
1509        self
1510    }
1511
1512    fn validate(&self) -> Result<(), String> {
1513        if self.fields.as_ref().map(|s| s.is_empty()).unwrap_or(false) {
1514            return Err("Field definitions cannot be empty".to_string());
1515        }
1516        Ok(())
1517    }
1518}
1519
1520impl TaggedCreateUserDefinedTypeStatementBuilder {
1521    fn validate(&self) -> Result<(), String> {
1522        if self.fields.as_ref().map(|s| s.is_empty()).unwrap_or(false) {
1523            return Err("Field definitions cannot be empty".to_string());
1524        }
1525        Ok(())
1526    }
1527}
1528
1529impl Parse for TaggedCreateUserDefinedTypeStatement {
1530    type Output = Self;
1531    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1532        s.parse::<(CREATE, TYPE)>()?;
1533        let mut res = TaggedCreateUserDefinedTypeStatementBuilder::default();
1534        res.set_if_not_exists(s.parse::<Option<(IF, NOT, EXISTS)>>()?.is_some())
1535            .name(s.parse()?)
1536            .fields(s.parse_from::<Parens<List<FieldDefinition, Comma>>>()?);
1537        s.parse::<Option<Semicolon>>()?;
1538        Ok(res
1539            .build()
1540            .map_err(|e| anyhow::anyhow!("Invalid CREATE TYPE statement: {}", e))?)
1541    }
1542}
1543
1544impl Display for CreateUserDefinedTypeStatement {
1545    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1546        write!(
1547            f,
1548            "CREATE TYPE{} {} ({})",
1549            if self.if_not_exists { " IF NOT EXISTS" } else { "" },
1550            self.name,
1551            self.fields.iter().map(|f| f.to_string()).collect::<Vec<_>>().join(", ")
1552        )
1553    }
1554}
1555
1556#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1557#[builder(build_fn(validate = "Self::validate"))]
1558#[parse_via(TaggedAlterUserDefinedTypeStatement)]
1559pub struct AlterUserDefinedTypeStatement {
1560    #[builder(setter(into))]
1561    pub name: KeyspaceQualifiedName,
1562    pub instruction: AlterTypeInstruction,
1563}
1564
1565impl TryFrom<TaggedAlterUserDefinedTypeStatement> for AlterUserDefinedTypeStatement {
1566    type Error = anyhow::Error;
1567    fn try_from(value: TaggedAlterUserDefinedTypeStatement) -> Result<Self, Self::Error> {
1568        Ok(Self {
1569            name: value.name.try_into()?,
1570            instruction: value.instruction,
1571        })
1572    }
1573}
1574
1575#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1576#[builder(build_fn(validate = "Self::validate"))]
1577#[tokenize_as(AlterUserDefinedTypeStatement)]
1578pub struct TaggedAlterUserDefinedTypeStatement {
1579    pub name: TaggedKeyspaceQualifiedName,
1580    pub instruction: AlterTypeInstruction,
1581}
1582
1583impl AlterUserDefinedTypeStatementBuilder {
1584    fn validate(&self) -> Result<(), String> {
1585        if self
1586            .instruction
1587            .as_ref()
1588            .map(|s| match s {
1589                AlterTypeInstruction::Rename(s) => s.is_empty(),
1590                _ => false,
1591            })
1592            .unwrap_or(false)
1593        {
1594            return Err("RENAME clause cannot be empty".to_string());
1595        }
1596        Ok(())
1597    }
1598}
1599
1600impl TaggedAlterUserDefinedTypeStatementBuilder {
1601    fn validate(&self) -> Result<(), String> {
1602        if self
1603            .instruction
1604            .as_ref()
1605            .map(|s| match s {
1606                AlterTypeInstruction::Rename(s) => s.is_empty(),
1607                _ => false,
1608            })
1609            .unwrap_or(false)
1610        {
1611            return Err("RENAME clause cannot be empty".to_string());
1612        }
1613        Ok(())
1614    }
1615}
1616
1617impl Parse for TaggedAlterUserDefinedTypeStatement {
1618    type Output = Self;
1619    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1620        s.parse::<(ALTER, TYPE)>()?;
1621        let mut res = TaggedAlterUserDefinedTypeStatementBuilder::default();
1622        res.name(s.parse()?).instruction(s.parse()?);
1623        s.parse::<Option<Semicolon>>()?;
1624        Ok(res
1625            .build()
1626            .map_err(|e| anyhow::anyhow!("Invalid ALTER TYPE statement: {}", e))?)
1627    }
1628}
1629
1630impl Display for AlterUserDefinedTypeStatement {
1631    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1632        write!(f, "ALTER TYPE {} {}", self.name, self.instruction)
1633    }
1634}
1635
1636#[derive(ParseFromStr, Clone, Debug, ToTokens, PartialEq, Eq)]
1637pub enum AlterTypeInstruction {
1638    Add(FieldDefinition),
1639    Rename(Vec<(Name, Name)>),
1640}
1641
1642impl AlterTypeInstruction {
1643    pub fn add<T: Into<FieldDefinition>>(field: T) -> Self {
1644        Self::Add(field.into())
1645    }
1646
1647    pub fn rename(renames: Vec<(impl Into<Name>, impl Into<Name>)>) -> Self {
1648        Self::Rename(renames.into_iter().map(|(from, to)| (from.into(), to.into())).collect())
1649    }
1650}
1651
1652impl Parse for AlterTypeInstruction {
1653    type Output = Self;
1654    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1655        Ok(if s.parse::<Option<ADD>>()?.is_some() {
1656            Self::Add(s.parse()?)
1657        } else if s.parse::<Option<RENAME>>()?.is_some() {
1658            Self::Rename(
1659                s.parse_from::<List<(Name, TO, Name), Nothing>>()?
1660                    .into_iter()
1661                    .map(|(a, _, b)| (a, b))
1662                    .collect(),
1663            )
1664        } else {
1665            anyhow::bail!("Invalid ALTER TYPE instruction!");
1666        })
1667    }
1668}
1669
1670impl Display for AlterTypeInstruction {
1671    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1672        match self {
1673            Self::Add(d) => write!(f, "ADD {}", d),
1674            Self::Rename(renames) => {
1675                let renames = renames
1676                    .iter()
1677                    .map(|(a, b)| format!(" {} TO {}", a, b))
1678                    .collect::<String>();
1679                write!(f, "RENAME{}", renames)
1680            }
1681        }
1682    }
1683}
1684
1685#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1686#[parse_via(TaggedDropUserDefinedTypeStatement)]
1687pub struct DropUserDefinedTypeStatement {
1688    #[builder(setter(name = "set_if_exists"), default)]
1689    pub if_exists: bool,
1690    #[builder(setter(into))]
1691    pub name: KeyspaceQualifiedName,
1692}
1693
1694impl TryFrom<TaggedDropUserDefinedTypeStatement> for DropUserDefinedTypeStatement {
1695    type Error = anyhow::Error;
1696    fn try_from(value: TaggedDropUserDefinedTypeStatement) -> Result<Self, Self::Error> {
1697        Ok(Self {
1698            if_exists: value.if_exists,
1699            name: value.name.try_into()?,
1700        })
1701    }
1702}
1703
1704#[derive(ParseFromStr, Builder, Clone, Debug, ToTokens, PartialEq, Eq)]
1705#[tokenize_as(DropUserDefinedTypeStatement)]
1706pub struct TaggedDropUserDefinedTypeStatement {
1707    #[builder(setter(name = "set_if_exists"), default)]
1708    pub if_exists: bool,
1709    pub name: TaggedKeyspaceQualifiedName,
1710}
1711
1712impl DropUserDefinedTypeStatementBuilder {
1713    /// Set IF EXISTS on the statement.
1714    /// To undo this, use `set_if_exists(false)`.
1715    pub fn if_exists(&mut self) -> &mut Self {
1716        self.if_exists.replace(true);
1717        self
1718    }
1719}
1720
1721impl Parse for TaggedDropUserDefinedTypeStatement {
1722    type Output = Self;
1723    fn parse(s: &mut StatementStream<'_>) -> anyhow::Result<Self::Output> {
1724        s.parse::<(DROP, TYPE)>()?;
1725        let mut res = TaggedDropUserDefinedTypeStatementBuilder::default();
1726        res.set_if_exists(s.parse::<Option<(IF, EXISTS)>>()?.is_some())
1727            .name(s.parse()?);
1728        s.parse::<Option<Semicolon>>()?;
1729        Ok(res
1730            .build()
1731            .map_err(|e| anyhow::anyhow!("Invalid DROP TYPE statement: {}", e))?)
1732    }
1733}
1734
1735impl Display for DropUserDefinedTypeStatement {
1736    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1737        write!(
1738            f,
1739            "DROP TYPE{} {}",
1740            if self.if_exists { " IF EXISTS" } else { "" },
1741            self.name
1742        )
1743    }
1744}
1745
1746#[cfg(test)]
1747mod test {
1748    use crate::{
1749        CollectionType,
1750        Constant,
1751        KeyspaceQualifyExt,
1752        NativeType,
1753    };
1754
1755    use super::*;
1756
1757    #[test]
1758    fn test_parse_create_role() {
1759        let mut builder = CreateRoleStatementBuilder::default();
1760        builder.name("test_role");
1761        let statement = builder.build().unwrap().to_string();
1762        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1763        builder.options(maplit::btreeset! {
1764            RoleOpt::password("test_password"),
1765        });
1766        let statement = builder.build().unwrap().to_string();
1767        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1768        builder.if_not_exists();
1769        let statement = builder.build().unwrap().to_string();
1770        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1771        builder.options(maplit::btreeset! {
1772            RoleOpt::password("test_password"),
1773            RoleOpt::login(true),
1774            RoleOpt::superuser(false),
1775            RoleOpt::access_to_datacenters(maplit::btreeset!{
1776                Constant::string("dc1"),
1777                Constant::string("dc2"),
1778            }),
1779            RoleOpt::access_to_all_datacenters(),
1780            RoleOpt::options(maplit::btreemap! {
1781                Constant::string("custom_option1") => Constant::string("custom value1"),
1782                Constant::string("custom_option2") => 99_i32.into(),
1783            })
1784        });
1785        let statement = builder.build().unwrap().to_string();
1786        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1787    }
1788
1789    #[test]
1790    fn test_parse_alter_role() {
1791        let mut builder = AlterRoleStatementBuilder::default();
1792        builder.name("test_role");
1793        assert!(builder.build().is_err());
1794        builder.options(BTreeSet::new());
1795        assert!(builder.build().is_err());
1796        builder.options(maplit::btreeset! {
1797            RoleOpt::password("test_password"),
1798        });
1799        let statement = builder.build().unwrap().to_string();
1800        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1801        builder.options(maplit::btreeset! {
1802            RoleOpt::password("test_password"),
1803            RoleOpt::login(true),
1804            RoleOpt::superuser(false),
1805            RoleOpt::access_to_datacenters(maplit::btreeset!{
1806                Constant::string("dc1"),
1807                Constant::string("dc2"),
1808            }),
1809            RoleOpt::access_to_all_datacenters(),
1810            RoleOpt::options(maplit::btreemap! {
1811                Constant::string("custom_option1") => Constant::string("custom value1"),
1812                Constant::string("custom_option2") => 99_i32.into(),
1813            })
1814        });
1815    }
1816
1817    #[test]
1818    fn test_parse_drop_role() {
1819        let mut builder = DropRoleStatementBuilder::default();
1820        builder.name("test_role");
1821        let statement = builder.build().unwrap().to_string();
1822        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1823        builder.if_exists();
1824        let statement = builder.build().unwrap().to_string();
1825        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1826    }
1827
1828    #[test]
1829    fn test_parse_grant_role() {
1830        let mut builder = GrantRoleStatementBuilder::default();
1831        builder.name("test_role");
1832        assert!(builder.build().is_err());
1833        builder.to("test_person");
1834        let statement = builder.build().unwrap().to_string();
1835        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1836    }
1837
1838    #[test]
1839    fn test_parse_revoke_role() {
1840        let mut builder = RevokeRoleStatementBuilder::default();
1841        builder.name("test_role");
1842        assert!(builder.build().is_err());
1843        builder.from("test_person");
1844        let statement = builder.build().unwrap().to_string();
1845        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1846    }
1847
1848    #[test]
1849    fn test_parse_list_roles() {
1850        let mut builder = ListRolesStatementBuilder::default();
1851        let statement = builder.build().unwrap().to_string();
1852        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1853        builder.of("test_person");
1854        let statement = builder.build().unwrap().to_string();
1855        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1856        builder.no_recursive();
1857        let statement = builder.build().unwrap().to_string();
1858        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1859    }
1860
1861    #[test]
1862    fn test_parse_grant_permission() {
1863        let mut builder = GrantPermissionStatementBuilder::default();
1864        builder.permission(Permission::Create);
1865        assert!(builder.build().is_err());
1866        builder.resource(Resource::keyspace("test_keyspace"));
1867        assert!(builder.build().is_err());
1868        builder.to("test_person");
1869        let statement = builder.build().unwrap().to_string();
1870        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1871        builder.permission(Permission::Alter);
1872        let statement = builder.build().unwrap().to_string();
1873        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1874        builder.permission(Permission::Drop);
1875        let statement = builder.build().unwrap().to_string();
1876        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1877        builder.permission(Permission::Select);
1878        let statement = builder.build().unwrap().to_string();
1879        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1880        builder.permission(Permission::Modify);
1881        let statement = builder.build().unwrap().to_string();
1882        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1883        builder.permission(Permission::Authorize);
1884        let statement = builder.build().unwrap().to_string();
1885        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1886        builder.permission(Permission::Describe);
1887        let statement = builder.build().unwrap().to_string();
1888        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1889        builder.permission(Permission::Execute);
1890        let statement = builder.build().unwrap().to_string();
1891        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1892        builder.permission(PermissionKind::All);
1893        let statement = builder.build().unwrap().to_string();
1894        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1895        builder.resource(Resource::all_keyspaces());
1896        let statement = builder.build().unwrap().to_string();
1897        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1898        builder.resource(Resource::table("test_table"));
1899        let statement = builder.build().unwrap().to_string();
1900        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1901        builder.resource(Resource::all_roles());
1902        let statement = builder.build().unwrap().to_string();
1903        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1904        builder.resource(Resource::role("test_role"));
1905        let statement = builder.build().unwrap().to_string();
1906        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1907        builder.resource(Resource::all_functions_in_keyspace("test_keyspace"));
1908        let statement = builder.build().unwrap().to_string();
1909        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1910        builder.resource(Resource::all_functions());
1911        let statement = builder.build().unwrap().to_string();
1912        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1913        builder.resource(Resource::function("test_keyspace".dot("func")));
1914        let statement = builder.build().unwrap().to_string();
1915        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1916        builder.resource(Resource::all_mbeans());
1917        let statement = builder.build().unwrap().to_string();
1918        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1919        builder.resource(Resource::mbean("test_mbean"));
1920        let statement = builder.build().unwrap().to_string();
1921        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1922    }
1923
1924    #[test]
1925    fn test_parse_revoke_permission() {
1926        let mut builder = RevokePermissionStatementBuilder::default();
1927        builder.permission(PermissionKind::All);
1928        assert!(builder.build().is_err());
1929        builder.resource(Resource::keyspace("test_keyspace"));
1930        assert!(builder.build().is_err());
1931        builder.from("test_person");
1932        let statement = builder.build().unwrap().to_string();
1933        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1934        builder.permission(Permission::Alter);
1935        let statement = builder.build().unwrap().to_string();
1936        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1937        builder.permission(Permission::Drop);
1938        let statement = builder.build().unwrap().to_string();
1939        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1940        builder.permission(Permission::Select);
1941        let statement = builder.build().unwrap().to_string();
1942        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1943        builder.permission(Permission::Modify);
1944        let statement = builder.build().unwrap().to_string();
1945        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1946        builder.permission(Permission::Authorize);
1947        let statement = builder.build().unwrap().to_string();
1948        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1949        builder.permission(Permission::Describe);
1950        let statement = builder.build().unwrap().to_string();
1951        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1952        builder.permission(Permission::Execute);
1953        let statement = builder.build().unwrap().to_string();
1954        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1955        builder.permission(Permission::Create);
1956        let statement = builder.build().unwrap().to_string();
1957        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1958        builder.resource(Resource::all_keyspaces());
1959        let statement = builder.build().unwrap().to_string();
1960        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1961        builder.resource(Resource::table("test_table"));
1962        let statement = builder.build().unwrap().to_string();
1963        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1964        builder.resource(Resource::all_roles());
1965        let statement = builder.build().unwrap().to_string();
1966        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1967        builder.resource(Resource::role("test_role"));
1968        let statement = builder.build().unwrap().to_string();
1969        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1970        builder.resource(Resource::all_functions_in_keyspace("test_keyspace"));
1971        let statement = builder.build().unwrap().to_string();
1972        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1973        builder.resource(Resource::all_functions());
1974        let statement = builder.build().unwrap().to_string();
1975        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1976        builder.resource(Resource::function("test_keyspace".dot("func")));
1977        let statement = builder.build().unwrap().to_string();
1978        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1979        builder.resource(Resource::all_mbeans());
1980        let statement = builder.build().unwrap().to_string();
1981        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1982        builder.resource(Resource::mbean("test_mbean"));
1983        let statement = builder.build().unwrap().to_string();
1984        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1985    }
1986
1987    #[test]
1988    fn test_parse_list_permissions() {
1989        let mut builder = ListPermissionsStatementBuilder::default();
1990        builder.permission(PermissionKind::All);
1991        let statement = builder.build().unwrap().to_string();
1992        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1993        builder.resource(Resource::keyspace("test_keyspace"));
1994        let statement = builder.build().unwrap().to_string();
1995        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1996        builder.of("test_person");
1997        let statement = builder.build().unwrap().to_string();
1998        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
1999        builder.no_recursive();
2000        let statement = builder.build().unwrap().to_string();
2001        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2002        builder.permission(Permission::Alter);
2003        let statement = builder.build().unwrap().to_string();
2004        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2005        builder.permission(Permission::Drop);
2006        let statement = builder.build().unwrap().to_string();
2007        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2008        builder.permission(Permission::Select);
2009        let statement = builder.build().unwrap().to_string();
2010        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2011        builder.permission(Permission::Modify);
2012        let statement = builder.build().unwrap().to_string();
2013        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2014        builder.permission(Permission::Authorize);
2015        let statement = builder.build().unwrap().to_string();
2016        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2017        builder.permission(Permission::Describe);
2018        let statement = builder.build().unwrap().to_string();
2019        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2020        builder.permission(Permission::Execute);
2021        let statement = builder.build().unwrap().to_string();
2022        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2023        builder.permission(Permission::Create);
2024        let statement = builder.build().unwrap().to_string();
2025        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2026        builder.resource(Resource::all_keyspaces());
2027        let statement = builder.build().unwrap().to_string();
2028        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2029        builder.resource(Resource::table("test_table"));
2030        let statement = builder.build().unwrap().to_string();
2031        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2032        builder.resource(Resource::all_roles());
2033        let statement = builder.build().unwrap().to_string();
2034        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2035        builder.resource(Resource::role("test_role"));
2036        let statement = builder.build().unwrap().to_string();
2037        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2038        builder.resource(Resource::all_functions_in_keyspace("test_keyspace"));
2039        let statement = builder.build().unwrap().to_string();
2040        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2041        builder.resource(Resource::all_functions());
2042        let statement = builder.build().unwrap().to_string();
2043        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2044        builder.resource(Resource::function("test_keyspace".dot("func")));
2045        let statement = builder.build().unwrap().to_string();
2046        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2047        builder.resource(Resource::all_mbeans());
2048        let statement = builder.build().unwrap().to_string();
2049        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2050        builder.resource(Resource::mbean("test_mbean"));
2051        let statement = builder.build().unwrap().to_string();
2052        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2053    }
2054
2055    #[test]
2056    fn test_parse_create_user() {
2057        let mut builder = CreateUserStatementBuilder::default();
2058        builder.name("test_person");
2059        let statement = builder.build().unwrap().to_string();
2060        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2061        builder.with_password("test_password");
2062        let statement = builder.build().unwrap().to_string();
2063        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2064        builder.superuser(true);
2065        let statement = builder.build().unwrap().to_string();
2066        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2067        builder.superuser(false);
2068        let statement = builder.build().unwrap().to_string();
2069        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2070        builder.if_not_exists();
2071        let statement = builder.build().unwrap().to_string();
2072        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2073    }
2074
2075    #[test]
2076    fn test_parse_alter_user() {
2077        let mut builder = AlterUserStatementBuilder::default();
2078        builder.name("test_person");
2079        let statement = builder.build().unwrap().to_string();
2080        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2081        builder.with_password("test_password");
2082        let statement = builder.build().unwrap().to_string();
2083        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2084        builder.superuser(true);
2085        let statement = builder.build().unwrap().to_string();
2086        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2087        builder.superuser(false);
2088        let statement = builder.build().unwrap().to_string();
2089        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2090    }
2091
2092    #[test]
2093    fn test_parse_drop_user() {
2094        let mut builder = DropUserStatementBuilder::default();
2095        builder.name("test person");
2096        let statement = builder.build().unwrap().to_string();
2097        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2098        builder.if_exists();
2099        let statement = builder.build().unwrap().to_string();
2100        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2101    }
2102
2103    #[test]
2104    fn test_parse_list_users() {
2105        assert_eq!(ListUsersStatement, ListUsersStatement.to_string().parse().unwrap());
2106    }
2107
2108    #[test]
2109    fn test_parse_create_udt() {
2110        let mut builder = CreateUserDefinedTypeStatementBuilder::default();
2111        builder.name("test_udt");
2112        assert!(builder.build().is_err());
2113        builder.fields(vec![]);
2114        assert!(builder.build().is_err());
2115        builder.fields(vec![
2116            ("test_field1", NativeType::Int).into(),
2117            ("test field2", CollectionType::list(NativeType::Text)).into(),
2118        ]);
2119        let statement = builder.build().unwrap().to_string();
2120        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2121        builder.if_not_exists();
2122        let statement = builder.build().unwrap().to_string();
2123        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2124    }
2125
2126    #[test]
2127    fn test_parse_alter_udt() {
2128        let mut builder = AlterUserDefinedTypeStatementBuilder::default();
2129        builder.name("test_udt");
2130        assert!(builder.build().is_err());
2131        builder.instruction(AlterTypeInstruction::add((
2132            "test_field1",
2133            vec![NativeType::Float.into(), NativeType::Date.into()],
2134        )));
2135        let statement = builder.build().unwrap().to_string();
2136        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2137        builder.instruction(AlterTypeInstruction::rename(vec![
2138            ("test_field1", "tuple field"),
2139            ("test_field2", "list_field"),
2140        ]));
2141        let statement = builder.build().unwrap().to_string();
2142        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2143    }
2144
2145    #[test]
2146    fn test_parse_drop_udt() {
2147        let mut builder = DropUserDefinedTypeStatementBuilder::default();
2148        builder.name("test_udt");
2149        let statement = builder.build().unwrap().to_string();
2150        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2151        builder.if_exists();
2152        let statement = builder.build().unwrap().to_string();
2153        assert_eq!(builder.build().unwrap(), statement.parse().unwrap());
2154    }
2155}