1extern crate alloc;
2
3use alloc::string::{String, ToString};
4use alloc::vec::Vec;
5use ibc_types_core_client::Height;
6
7use core::str::FromStr;
12
13use ibc_types_core_channel::{packet::Sequence, ChannelId, PortId};
14use ibc_types_core_client::ClientId;
15use ibc_types_core_connection::ConnectionId;
16
17use derive_more::{Display, From};
18
19pub const IBC_QUERY_PATH: &str = "store/ibc/key";
21
22pub const SDK_UPGRADE_QUERY_PATH: &str = "store/upgrade/key";
25
26const UPGRADED_IBC_STATE: &str = "upgradedIBCState";
29const UPGRADED_CLIENT_STATE: &str = "upgradedClient";
31const UPGRADED_CLIENT_CONSENSUS_STATE: &str = "upgradedConsState";
33
34#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, From, Display)]
36pub enum Path {
37 ClientType(ClientTypePath),
38 ClientState(ClientStatePath),
39 ClientConsensusState(ClientConsensusStatePath),
40 ClientConnection(ClientConnectionPath),
41 Connection(ConnectionPath),
42 Ports(PortPath),
43 ChannelEnd(ChannelEndPath),
44 SeqSend(SeqSendPath),
45 SeqRecv(SeqRecvPath),
46 SeqAck(SeqAckPath),
47 Commitment(CommitmentPath),
48 Ack(AckPath),
49 Receipt(ReceiptPath),
50 Upgrade(ClientUpgradePath),
51}
52
53#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
54#[display(fmt = "clients/{_0}/clientType")]
55pub struct ClientTypePath(pub ClientId);
56
57impl ClientTypePath {
58 pub fn new(client_id: &ClientId) -> ClientTypePath {
59 ClientTypePath(client_id.clone())
60 }
61}
62
63#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
64#[display(fmt = "clients/{_0}/clientState")]
65pub struct ClientStatePath(pub ClientId);
66
67impl ClientStatePath {
68 pub fn new(client_id: &ClientId) -> ClientStatePath {
69 ClientStatePath(client_id.clone())
70 }
71}
72
73#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
74#[display(fmt = "clients/{client_id}/consensusStates/{epoch}-{height}")]
75pub struct ClientConsensusStatePath {
76 pub client_id: ClientId,
77 pub epoch: u64,
78 pub height: u64,
79}
80
81impl ClientConsensusStatePath {
82 pub fn new(client_id: &ClientId, height: &Height) -> ClientConsensusStatePath {
83 ClientConsensusStatePath {
84 client_id: client_id.clone(),
85 epoch: height.revision_number(),
86 height: height.revision_height(),
87 }
88 }
89}
90
91#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
92#[display(fmt = "clients/{_0}/connections")]
93pub struct ClientConnectionPath(pub ClientId);
94
95impl ClientConnectionPath {
96 pub fn new(client_id: &ClientId) -> ClientConnectionPath {
97 ClientConnectionPath(client_id.clone())
98 }
99}
100
101#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
102#[display(fmt = "connections/{_0}")]
103pub struct ConnectionPath(pub ConnectionId);
104
105impl ConnectionPath {
106 pub fn new(connection_id: &ConnectionId) -> ConnectionPath {
107 ConnectionPath(connection_id.clone())
108 }
109}
110
111#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
112#[display(fmt = "ports/{_0}")]
113pub struct PortPath(pub PortId);
114
115#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
116#[display(fmt = "channelEnds/ports/{_0}/channels/{_1}")]
117pub struct ChannelEndPath(pub PortId, pub ChannelId);
118
119impl ChannelEndPath {
120 pub fn new(port_id: &PortId, channel_id: &ChannelId) -> ChannelEndPath {
121 ChannelEndPath(port_id.clone(), channel_id.clone())
122 }
123}
124
125#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
126#[display(fmt = "nextSequenceSend/ports/{_0}/channels/{_1}")]
127pub struct SeqSendPath(pub PortId, pub ChannelId);
128
129impl SeqSendPath {
130 pub fn new(port_id: &PortId, channel_id: &ChannelId) -> SeqSendPath {
131 SeqSendPath(port_id.clone(), channel_id.clone())
132 }
133}
134
135#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
136#[display(fmt = "nextSequenceRecv/ports/{_0}/channels/{_1}")]
137pub struct SeqRecvPath(pub PortId, pub ChannelId);
138
139impl SeqRecvPath {
140 pub fn new(port_id: &PortId, channel_id: &ChannelId) -> SeqRecvPath {
141 SeqRecvPath(port_id.clone(), channel_id.clone())
142 }
143}
144
145#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
146#[display(fmt = "nextSequenceAck/ports/{_0}/channels/{_1}")]
147pub struct SeqAckPath(pub PortId, pub ChannelId);
148
149impl SeqAckPath {
150 pub fn new(port_id: &PortId, channel_id: &ChannelId) -> SeqAckPath {
151 SeqAckPath(port_id.clone(), channel_id.clone())
152 }
153}
154
155#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
156#[display(fmt = "commitments/ports/{port_id}/channels/{channel_id}/sequences/{sequence}")]
157pub struct CommitmentPath {
158 pub port_id: PortId,
159 pub channel_id: ChannelId,
160 pub sequence: Sequence,
161}
162
163impl CommitmentPath {
164 pub fn new(port_id: &PortId, channel_id: &ChannelId, sequence: Sequence) -> CommitmentPath {
165 CommitmentPath {
166 port_id: port_id.clone(),
167 channel_id: channel_id.clone(),
168 sequence,
169 }
170 }
171}
172
173#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
174#[display(fmt = "acks/ports/{port_id}/channels/{channel_id}/sequences/{sequence}")]
175pub struct AckPath {
176 pub port_id: PortId,
177 pub channel_id: ChannelId,
178 pub sequence: Sequence,
179}
180
181impl AckPath {
182 pub fn new(port_id: &PortId, channel_id: &ChannelId, sequence: Sequence) -> AckPath {
183 AckPath {
184 port_id: port_id.clone(),
185 channel_id: channel_id.clone(),
186 sequence,
187 }
188 }
189}
190
191#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
192#[display(fmt = "receipts/ports/{port_id}/channels/{channel_id}/sequences/{sequence}")]
193pub struct ReceiptPath {
194 pub port_id: PortId,
195 pub channel_id: ChannelId,
196 pub sequence: Sequence,
197}
198
199impl ReceiptPath {
200 pub fn new(port_id: &PortId, channel_id: &ChannelId, sequence: Sequence) -> ReceiptPath {
201 ReceiptPath {
202 port_id: port_id.clone(),
203 channel_id: channel_id.clone(),
204 sequence,
205 }
206 }
207}
208
209#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
211pub enum ClientUpgradePath {
212 #[display(fmt = "{UPGRADED_IBC_STATE}/{_0}/{UPGRADED_CLIENT_STATE}")]
213 UpgradedClientState(u64),
214 #[display(fmt = "{UPGRADED_IBC_STATE}/{_0}/{UPGRADED_CLIENT_CONSENSUS_STATE}")]
215 UpgradedClientConsensusState(u64),
216}
217
218#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
221enum SubPath {
222 Channels(ChannelId),
223 Sequences(Sequence),
224}
225
226impl Path {
227 pub fn is_provable(&self) -> bool {
229 !matches!(&self, Path::ClientConnection(_) | Path::Ports(_))
230 }
231
232 pub fn into_bytes(self) -> Vec<u8> {
234 self.to_string().into_bytes()
235 }
236}
237
238#[derive(Debug, displaydoc::Display)]
239pub enum PathError {
240 ParseFailure { path: String },
242}
243
244#[cfg(feature = "std")]
245impl std::error::Error for PathError {}
246
247impl FromStr for Path {
249 type Err = PathError;
250
251 fn from_str(s: &str) -> Result<Self, Self::Err> {
252 let components: Vec<&str> = s.split('/').collect();
253
254 parse_client_paths(&components)
255 .or_else(|| parse_connections(&components))
256 .or_else(|| parse_ports(&components))
257 .or_else(|| parse_channel_ends(&components))
258 .or_else(|| parse_seqs(&components))
259 .or_else(|| parse_commitments(&components))
260 .or_else(|| parse_acks(&components))
261 .or_else(|| parse_receipts(&components))
262 .or_else(|| parse_upgrades(&components))
263 .ok_or(PathError::ParseFailure {
264 path: s.to_string(),
265 })
266 }
267}
268
269fn parse_client_paths(components: &[&str]) -> Option<Path> {
270 let first = match components.first() {
271 Some(f) => *f,
272 None => return None,
273 };
274
275 if first != "clients" {
276 return None;
277 }
278
279 let client_id = match ClientId::from_str(components[1]) {
280 Ok(s) => s,
281 Err(_) => return None,
282 };
283
284 if components.len() == 3 {
285 match components[2] {
286 "clientType" => Some(ClientTypePath(client_id).into()),
287 "clientState" => Some(ClientStatePath(client_id).into()),
288 "connections" => Some(ClientConnectionPath(client_id).into()),
289 _ => None,
290 }
291 } else if components.len() == 4 {
292 if "consensusStates" != components[2] {
293 return None;
294 }
295
296 let epoch_height = match components.last() {
297 Some(eh) => *eh,
298 None => return None,
299 };
300
301 let epoch_height: Vec<&str> = epoch_height.split('-').collect();
302
303 if epoch_height.len() != 2 {
304 return None;
305 }
306
307 let epoch = epoch_height[0];
308 let height = epoch_height[1];
309
310 let epoch = match epoch.parse::<u64>() {
311 Ok(ep) => ep,
312 Err(_) => return None,
313 };
314
315 let height = match height.parse::<u64>() {
316 Ok(h) => h,
317 Err(_) => return None,
318 };
319
320 Some(
321 ClientConsensusStatePath {
322 client_id,
323 epoch,
324 height,
325 }
326 .into(),
327 )
328 } else {
329 None
330 }
331}
332
333fn parse_connections(components: &[&str]) -> Option<Path> {
334 if components.len() != 2 {
335 return None;
336 }
337
338 let first = match components.first() {
339 Some(f) => *f,
340 None => return None,
341 };
342
343 if first != "connections" {
344 return None;
345 }
346
347 let connection_id = match components.last() {
348 Some(c) => *c,
349 None => return None,
350 };
351
352 let connection_id = match ConnectionId::from_str(connection_id) {
353 Ok(c) => c,
354 Err(_) => return None,
355 };
356
357 Some(ConnectionPath(connection_id).into())
358}
359
360fn parse_ports(components: &[&str]) -> Option<Path> {
361 if components.len() != 2 {
362 return None;
363 }
364
365 let first = match components.first() {
366 Some(f) => *f,
367 None => return None,
368 };
369
370 if first != "ports" {
371 return None;
372 }
373
374 let port_id = match components.last() {
375 Some(p) => *p,
376 None => return None,
377 };
378
379 let port_id = match PortId::from_str(port_id) {
380 Ok(p) => p,
381 Err(_) => return None,
382 };
383
384 Some(PortPath(port_id).into())
385}
386
387fn parse_channels(components: &[&str]) -> Option<SubPath> {
388 if components.len() != 2 {
389 return None;
390 }
391
392 let first = match components.first() {
393 Some(f) => *f,
394 None => return None,
395 };
396
397 if first != "channels" {
398 return None;
399 }
400
401 let channel_id = match components.last() {
402 Some(c) => *c,
403 None => return None,
404 };
405
406 let channel_id = match ChannelId::from_str(channel_id) {
407 Ok(c) => c,
408 Err(_) => return None,
409 };
410
411 Some(SubPath::Channels(channel_id))
412}
413
414fn parse_sequences(components: &[&str]) -> Option<SubPath> {
415 if components.len() != 2 {
416 return None;
417 }
418
419 let first = match components.first() {
420 Some(f) => *f,
421 None => return None,
422 };
423
424 if first != "sequences" {
425 return None;
426 }
427
428 let sequence_number = match components.last() {
429 Some(s) => *s,
430 None => return None,
431 };
432
433 match Sequence::from_str(sequence_number) {
434 Ok(seq) => Some(SubPath::Sequences(seq)),
435 Err(_) => None,
436 }
437}
438
439fn parse_channel_ends(components: &[&str]) -> Option<Path> {
440 if components.len() != 5 {
441 return None;
442 }
443
444 let first = match components.first() {
445 Some(f) => *f,
446 None => return None,
447 };
448
449 if first != "channelEnds" {
450 return None;
451 }
452
453 let port = parse_ports(&components[1..=2]);
454 let channel = parse_channels(&components[3..=4]);
455
456 let port_id = if let Some(Path::Ports(PortPath(port_id))) = port {
457 port_id
458 } else {
459 return None;
460 };
461
462 let channel_id = if let Some(SubPath::Channels(channel_id)) = channel {
463 channel_id
464 } else {
465 return None;
466 };
467
468 Some(ChannelEndPath(port_id, channel_id).into())
469}
470
471fn parse_seqs(components: &[&str]) -> Option<Path> {
472 if components.len() != 5 {
473 return None;
474 }
475
476 let first = match components.first() {
477 Some(f) => *f,
478 None => return None,
479 };
480
481 let port = parse_ports(&components[1..=2]);
482 let channel = parse_channels(&components[3..=4]);
483
484 let port_id = if let Some(Path::Ports(PortPath(port_id))) = port {
485 port_id
486 } else {
487 return None;
488 };
489
490 let channel_id = if let Some(SubPath::Channels(channel_id)) = channel {
491 channel_id
492 } else {
493 return None;
494 };
495
496 match first {
497 "nextSequenceSend" => Some(SeqSendPath(port_id, channel_id).into()),
498 "nextSequenceRecv" => Some(SeqRecvPath(port_id, channel_id).into()),
499 "nextSequenceAck" => Some(SeqAckPath(port_id, channel_id).into()),
500 _ => None,
501 }
502}
503
504fn parse_commitments(components: &[&str]) -> Option<Path> {
505 if components.len() != 7 {
506 return None;
507 }
508
509 let first = match components.first() {
510 Some(f) => *f,
511 None => return None,
512 };
513
514 if first != "commitments" {
515 return None;
516 }
517
518 let port = parse_ports(&components[1..=2]);
519 let channel = parse_channels(&components[3..=4]);
520 let sequence = parse_sequences(&components[5..]);
521
522 let port_id = if let Some(Path::Ports(PortPath(port_id))) = port {
523 port_id
524 } else {
525 return None;
526 };
527
528 let channel_id = if let Some(SubPath::Channels(channel_id)) = channel {
529 channel_id
530 } else {
531 return None;
532 };
533
534 let sequence = if let Some(SubPath::Sequences(seq)) = sequence {
535 seq
536 } else {
537 return None;
538 };
539
540 Some(
541 CommitmentPath {
542 port_id,
543 channel_id,
544 sequence,
545 }
546 .into(),
547 )
548}
549
550fn parse_acks(components: &[&str]) -> Option<Path> {
551 if components.len() != 7 {
552 return None;
553 }
554
555 let first = match components.first() {
556 Some(f) => *f,
557 None => return None,
558 };
559
560 if first != "acks" {
561 return None;
562 }
563
564 let port = parse_ports(&components[1..=2]);
565 let channel = parse_channels(&components[3..=4]);
566 let sequence = parse_sequences(&components[5..]);
567
568 let port_id = if let Some(Path::Ports(PortPath(port_id))) = port {
569 port_id
570 } else {
571 return None;
572 };
573
574 let channel_id = if let Some(SubPath::Channels(channel_id)) = channel {
575 channel_id
576 } else {
577 return None;
578 };
579
580 let sequence = if let Some(SubPath::Sequences(seq)) = sequence {
581 seq
582 } else {
583 return None;
584 };
585
586 Some(
587 AckPath {
588 port_id,
589 channel_id,
590 sequence,
591 }
592 .into(),
593 )
594}
595
596fn parse_receipts(components: &[&str]) -> Option<Path> {
597 if components.len() != 7 {
598 return None;
599 }
600
601 let first = match components.first() {
602 Some(f) => *f,
603 None => return None,
604 };
605
606 if first != "receipts" {
607 return None;
608 }
609
610 let port = parse_ports(&components[1..=2]);
611 let channel = parse_channels(&components[3..=4]);
612 let sequence = parse_sequences(&components[5..]);
613
614 let port_id = if let Some(Path::Ports(PortPath(port_id))) = port {
615 port_id
616 } else {
617 return None;
618 };
619
620 let channel_id = if let Some(SubPath::Channels(channel_id)) = channel {
621 channel_id
622 } else {
623 return None;
624 };
625
626 let sequence = if let Some(SubPath::Sequences(seq)) = sequence {
627 seq
628 } else {
629 return None;
630 };
631
632 Some(
633 ReceiptPath {
634 port_id,
635 channel_id,
636 sequence,
637 }
638 .into(),
639 )
640}
641
642fn parse_upgrades(components: &[&str]) -> Option<Path> {
643 if components.len() != 3 {
644 return None;
645 }
646
647 let first = match components.first() {
648 Some(f) => *f,
649 None => return None,
650 };
651
652 if first != UPGRADED_IBC_STATE {
653 return None;
654 }
655
656 let last = match components.last() {
657 Some(l) => *l,
658 None => return None,
659 };
660
661 let height = match components[1].parse::<u64>() {
662 Ok(h) => h,
663 Err(_) => return None,
664 };
665
666 match last {
667 UPGRADED_CLIENT_STATE => Some(ClientUpgradePath::UpgradedClientState(height).into()),
668 UPGRADED_CLIENT_CONSENSUS_STATE => {
669 Some(ClientUpgradePath::UpgradedClientConsensusState(height).into())
670 }
671 _ => None,
672 }
673}
674
675#[cfg(test)]
676mod tests {
677 use super::*;
678 use core::str::FromStr;
679
680 #[test]
681 fn invalid_path_doesnt_parse() {
682 let invalid_path = Path::from_str("clients/clientType");
683
684 assert!(invalid_path.is_err());
685 }
686
687 #[test]
688 fn test_parse_client_paths_fn() {
689 let path = "clients/07-tendermint-0/clientType";
690 let components: Vec<&str> = path.split('/').collect();
691
692 assert_eq!(
693 parse_client_paths(&components),
694 Some(Path::ClientType(ClientTypePath(ClientId::default())))
695 );
696
697 let path = "clients/07-tendermint-0/clientState";
698 let components: Vec<&str> = path.split('/').collect();
699
700 assert_eq!(
701 parse_client_paths(&components),
702 Some(Path::ClientState(ClientStatePath(ClientId::default())))
703 );
704
705 let path = "clients/07-tendermint-0/consensusStates/15-31";
706 let components: Vec<&str> = path.split('/').collect();
707
708 assert_eq!(
709 parse_client_paths(&components),
710 Some(Path::ClientConsensusState(ClientConsensusStatePath {
711 client_id: ClientId::default(),
712 epoch: 15,
713 height: 31,
714 }))
715 );
716 }
717
718 #[test]
719 fn client_type_path_parses() {
720 let path = "clients/07-tendermint-0/clientType";
721 let path = Path::from_str(path);
722
723 assert!(path.is_ok());
724 assert_eq!(
725 path.unwrap(),
726 Path::ClientType(ClientTypePath(ClientId::default()))
727 );
728 }
729
730 #[test]
731 fn client_state_path_parses() {
732 let path = "clients/07-tendermint-0/clientState";
733 let path = Path::from_str(path);
734
735 assert!(path.is_ok());
736 assert_eq!(
737 path.unwrap(),
738 Path::ClientState(ClientStatePath(ClientId::default()))
739 );
740 }
741
742 #[test]
743 fn client_consensus_state_path_parses() {
744 let path = "clients/07-tendermint-0/consensusStates/15-31";
745 let path = Path::from_str(path);
746
747 assert!(path.is_ok());
748 assert_eq!(
749 path.unwrap(),
750 Path::ClientConsensusState(ClientConsensusStatePath {
751 client_id: ClientId::default(),
752 epoch: 15,
753 height: 31,
754 })
755 );
756 }
757
758 #[test]
759 fn client_connections_path_parses() {
760 let path = "clients/07-tendermint-0/connections";
761 let path = Path::from_str(path);
762
763 assert!(path.is_ok());
764 assert_eq!(
765 path.unwrap(),
766 Path::ClientConnection(ClientConnectionPath(ClientId::default()))
767 );
768 }
769
770 #[test]
771 fn test_parse_connections_fn() {
772 let path = "connections/connection-0";
773 let components: Vec<&str> = path.split('/').collect();
774
775 assert_eq!(
776 parse_connections(&components),
777 Some(Path::Connection(ConnectionPath(ConnectionId::new(0)))),
778 );
779 }
780
781 #[test]
782 fn connections_path_parses() {
783 let path = "connections/connection-0";
784 let path = Path::from_str(path);
785
786 assert!(path.is_ok());
787 assert_eq!(
788 path.unwrap(),
789 Path::Connection(ConnectionPath(ConnectionId::new(0)))
790 );
791 }
792
793 #[test]
794 fn test_parse_ports_fn() {
795 let path = "ports/defaultPort";
796 let components: Vec<&str> = path.split('/').collect();
797
798 assert_eq!(
799 parse_ports(&components),
800 Some(Path::Ports(PortPath(PortId::default()))),
801 );
802 }
803
804 #[test]
805 fn ports_path_parses() {
806 let path = "ports/defaultPort";
807 let path = Path::from_str(path);
808
809 assert!(path.is_ok());
810 assert_eq!(path.unwrap(), Path::Ports(PortPath(PortId::default())));
811 }
812
813 #[test]
814 fn test_parse_channels_fn() {
815 let path = "channels/channel-0";
816 let components: Vec<&str> = path.split('/').collect();
817
818 assert_eq!(
819 parse_channels(&components),
820 Some(SubPath::Channels(ChannelId::default())),
821 );
822 }
823
824 #[test]
825 fn channels_path_doesnt_parse() {
826 let path = "channels/channel-0";
827 let path = Path::from_str(path);
828
829 assert!(path.is_err());
830 }
831
832 #[test]
833 fn test_parse_sequences_fn() {
834 let path = "sequences/0";
835 let components: Vec<&str> = path.split('/').collect();
836
837 assert_eq!(
838 parse_sequences(&components),
839 Some(SubPath::Sequences(Sequence::default()))
840 );
841 }
842
843 #[test]
844 fn sequences_path_doesnt_parse() {
845 let path = "sequences/0";
846 let path = Path::from_str(path);
847
848 assert!(path.is_err());
849 }
850
851 #[test]
852 fn test_parse_channel_ends_fn() {
853 let path = "channelEnds/ports/defaultPort/channels/channel-0";
854 let components: Vec<&str> = path.split('/').collect();
855
856 assert_eq!(
857 parse_channel_ends(&components),
858 Some(Path::ChannelEnd(ChannelEndPath(
859 PortId::default(),
860 ChannelId::default()
861 ))),
862 );
863 }
864
865 #[test]
866 fn channel_ends_path_parses() {
867 let path = "channelEnds/ports/defaultPort/channels/channel-0";
868 let path = Path::from_str(path);
869
870 assert!(path.is_ok());
871 assert_eq!(
872 path.unwrap(),
873 Path::ChannelEnd(ChannelEndPath(PortId::default(), ChannelId::default())),
874 );
875 }
876
877 #[test]
878 fn test_parse_seqs_fn() {
879 let path = "nextSequenceSend/ports/defaultPort/channels/channel-0";
880 let components: Vec<&str> = path.split('/').collect();
881
882 assert_eq!(
883 parse_seqs(&components),
884 Some(Path::SeqSend(SeqSendPath(
885 PortId::default(),
886 ChannelId::default()
887 ))),
888 );
889
890 let path = "nextSequenceRecv/ports/defaultPort/channels/channel-0";
891 let components: Vec<&str> = path.split('/').collect();
892
893 assert_eq!(
894 parse_seqs(&components),
895 Some(Path::SeqRecv(SeqRecvPath(
896 PortId::default(),
897 ChannelId::default()
898 ))),
899 );
900
901 let path = "nextSequenceAck/ports/defaultPort/channels/channel-0";
902 let components: Vec<&str> = path.split('/').collect();
903
904 assert_eq!(
905 parse_seqs(&components),
906 Some(Path::SeqAck(SeqAckPath(
907 PortId::default(),
908 ChannelId::default()
909 ))),
910 );
911 }
912
913 #[test]
914 fn sequence_send_path_parses() {
915 let path = "nextSequenceSend/ports/defaultPort/channels/channel-0";
916 let path = Path::from_str(path);
917
918 assert!(path.is_ok());
919 assert_eq!(
920 path.unwrap(),
921 Path::SeqSend(SeqSendPath(PortId::default(), ChannelId::default())),
922 );
923 }
924
925 #[test]
926 fn sequence_recv_path_parses() {
927 let path = "nextSequenceRecv/ports/defaultPort/channels/channel-0";
928 let path = Path::from_str(path);
929
930 assert!(path.is_ok());
931 assert_eq!(
932 path.unwrap(),
933 Path::SeqRecv(SeqRecvPath(PortId::default(), ChannelId::default())),
934 );
935 }
936
937 #[test]
938 fn sequence_ack_path_parses() {
939 let path = "nextSequenceAck/ports/defaultPort/channels/channel-0";
940 let path = Path::from_str(path);
941
942 assert!(path.is_ok());
943 assert_eq!(
944 path.unwrap(),
945 Path::SeqAck(SeqAckPath(PortId::default(), ChannelId::default())),
946 );
947 }
948
949 #[test]
950 fn test_parse_commitments_fn() {
951 let path = "commitments/ports/defaultPort/channels/channel-0/sequences/0";
952 let components: Vec<&str> = path.split('/').collect();
953
954 assert_eq!(
955 parse_commitments(&components),
956 Some(Path::Commitment(CommitmentPath {
957 port_id: PortId::default(),
958 channel_id: ChannelId::default(),
959 sequence: Sequence::default(),
960 })),
961 );
962 }
963
964 #[test]
965 fn commitments_path_parses() {
966 let path = "commitments/ports/defaultPort/channels/channel-0/sequences/0";
967 let path = Path::from_str(path);
968
969 assert!(path.is_ok());
970 assert_eq!(
971 path.unwrap(),
972 Path::Commitment(CommitmentPath {
973 port_id: PortId::default(),
974 channel_id: ChannelId::default(),
975 sequence: Sequence::default(),
976 }),
977 );
978 }
979
980 #[test]
981 fn test_parse_acks_fn() {
982 let path = "acks/ports/defaultPort/channels/channel-0/sequences/0";
983 let components: Vec<&str> = path.split('/').collect();
984
985 assert_eq!(
986 parse_acks(&components),
987 Some(Path::Ack(AckPath {
988 port_id: PortId::default(),
989 channel_id: ChannelId::default(),
990 sequence: Sequence::default(),
991 })),
992 );
993 }
994
995 #[test]
996 fn acks_path_parses() {
997 let path = "acks/ports/defaultPort/channels/channel-0/sequences/0";
998 let path = Path::from_str(path);
999
1000 assert!(path.is_ok());
1001 assert_eq!(
1002 path.unwrap(),
1003 Path::Ack(AckPath {
1004 port_id: PortId::default(),
1005 channel_id: ChannelId::default(),
1006 sequence: Sequence::default(),
1007 }),
1008 );
1009 }
1010
1011 #[test]
1012 fn test_parse_receipts_fn() {
1013 let path = "receipts/ports/defaultPort/channels/channel-0/sequences/0";
1014 let components: Vec<&str> = path.split('/').collect();
1015
1016 assert_eq!(
1017 parse_receipts(&components),
1018 Some(Path::Receipt(ReceiptPath {
1019 port_id: PortId::default(),
1020 channel_id: ChannelId::default(),
1021 sequence: Sequence::default(),
1022 })),
1023 );
1024 }
1025
1026 #[test]
1027 fn receipts_path_parses() {
1028 let path = "receipts/ports/defaultPort/channels/channel-0/sequences/0";
1029 let path = Path::from_str(path);
1030
1031 assert!(path.is_ok());
1032 assert_eq!(
1033 path.unwrap(),
1034 Path::Receipt(ReceiptPath {
1035 port_id: PortId::default(),
1036 channel_id: ChannelId::default(),
1037 sequence: Sequence::default(),
1038 }),
1039 );
1040 }
1041
1042 #[test]
1043 fn test_parse_upgrades_fn() {
1044 let path = "upgradedIBCState/0/upgradedClient";
1045 let components: Vec<&str> = path.split('/').collect();
1046
1047 assert_eq!(
1048 parse_upgrades(&components),
1049 Some(Path::Upgrade(ClientUpgradePath::UpgradedClientState(0))),
1050 );
1051
1052 let path = "upgradedIBCState/0/upgradedConsState";
1053 let components: Vec<&str> = path.split('/').collect();
1054
1055 assert_eq!(
1056 parse_upgrades(&components),
1057 Some(Path::Upgrade(
1058 ClientUpgradePath::UpgradedClientConsensusState(0)
1059 )),
1060 )
1061 }
1062
1063 #[test]
1064 fn upgrade_client_state_path_parses() {
1065 let path = "upgradedIBCState/0/upgradedClient";
1066 let path = Path::from_str(path);
1067
1068 assert!(path.is_ok());
1069 assert_eq!(
1070 path.unwrap(),
1071 Path::Upgrade(ClientUpgradePath::UpgradedClientState(0)),
1072 );
1073 }
1074
1075 #[test]
1076 fn upgrade_client_consensus_state_path_parses() {
1077 let path = "upgradedIBCState/0/upgradedConsState";
1078 let path = Path::from_str(path);
1079
1080 assert!(path.is_ok());
1081 assert_eq!(
1082 path.unwrap(),
1083 Path::Upgrade(ClientUpgradePath::UpgradedClientConsensusState(0)),
1084 );
1085 }
1086}