allfeat_midds/lib.rs
1// This file is part of Allfeat.
2
3// Copyright (C) 2022-2025 Allfeat.
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! # Allfeat MIDDS - Music Industry Decentralized Data Structures
20//!
21//! This crate provides Substrate-compatible implementations of MIDDS (Music Industry
22//! Decentralized Data Structures) for the Allfeat blockchain ecosystem.
23//!
24//! ## Overview
25//!
26//! MIDDS defines standardized data structures for representing music industry entities:
27//! - **Musical Works**: Compositions and songs (identified by ISWC)
28//! - **Party Identifiers**: Artists, publishers, and other music industry parties (identified by IPI/ISNI)
29//! - **Releases**: Albums, EPs, and other music releases (identified by EAN/UPC)
30//! - **Tracks**: Individual recordings (identified by ISRC)
31//!
32//! ## Key Features
33//!
34//! - 🔗 **Substrate Integration**: Full compatibility with Substrate/Polkadot ecosystem
35//! - 🛡️ **Type Safety**: Strong typing with comprehensive validation
36//! - 🚀 **Performance**: Optimized for on-chain storage and operations
37//! - 🔄 **Dual Types**: Separate SDK and Runtime types for optimal UX and efficiency
38//! - 📊 **Standards Compliant**: Implements music industry standard identifiers
39//!
40//! ## Quick Start
41//!
42//! ```rust
43//! use allfeat_midds::{
44//! party_identifier::Ipi,
45//! musical_work::Iswc,
46//! shared::conversion::Validatable,
47//! };
48//! use std::str::FromStr;
49//!
50//! // Create music industry identifiers
51//! let ipi: Ipi = 123456789;
52//! let iswc = Iswc::from_str("T1234567890").unwrap();
53//!
54//! // Validate identifiers (std feature required)
55//! #[cfg(feature = "std")]
56//! {
57//! assert!(iswc.validate().is_ok());
58//! }
59//! ```
60//!
61//! ## Architecture
62//!
63//! The crate is organized into several modules:
64//!
65//! - [`shared`]: Common types, identifiers, and utilities
66//! - [`musical_work`]: Musical work (composition) data structures
67//! - [`party_identifier`]: Party (artist/entity) identification
68//! - [`release`]: Music release data structures
69//! - [`track`]: Individual track/recording data structures
70//!
71//! Each module provides both SDK types (for application development) and Runtime types
72//! (for blockchain storage), with automatic conversion between them.
73//!
74//! ## Feature Flags
75//!
76//! - `std` (default): Enables SDK types and validation features
77//! - `try-runtime`: Enables try-runtime features for Substrate integration
78//! - `runtime-benchmarks`: Enables benchmarking utilities for Substrate pallets
79//!
80//! ## Benchmarking Support
81//!
82//! When the `runtime-benchmarks` feature is enabled, each MIDDS type provides
83//! benchmarking helpers to generate data of varying complexity for accurate
84//! weight calculation in Substrate pallets:
85//!
86//! ```rust,ignore
87//! use allfeat_midds::{
88//! benchmarking::BenchmarkHelperT,
89//! track::Track,
90//! Midds,
91//! };
92//!
93//! // Generate MIDDS with specific complexity (0.0 = minimal, 1.0 = maximal)
94//! let track = <Track as Midds>::BenchmarkHelper::variable_size(0.5);
95//!
96//! // Or use predefined sizes
97//! let min_track = <Track as Midds>::BenchmarkHelper::min_size();
98//! let max_track = <Track as Midds>::BenchmarkHelper::max_size();
99//! ```
100//!
101//! This enables precise weight calculation based on actual data size variations,
102//! following Substrate's best practices for benchmarking.
103
104#![cfg_attr(not(feature = "std"), no_std)]
105
106#[cfg(not(feature = "std"))]
107extern crate alloc;
108
109use frame_support::{
110 dispatch::DispatchResult, pallet_prelude::Member, Blake2_256, Parameter, StorageHasher,
111};
112use parity_scale_codec::MaxEncodedLen;
113
114// MIDDS modules
115pub mod musical_work;
116pub mod party_identifier;
117pub mod release;
118pub mod track;
119
120// Shared utilities
121pub mod shared;
122
123// Re-export conversion module at root level for MiddsSdk macro compatibility
124#[cfg(feature = "std")]
125pub use shared::conversion;
126
127// Benchmarking utilities
128#[cfg(feature = "runtime-benchmarks")]
129pub mod benchmarking;
130
131/// Generic Midds Identifier expected to be used for storing in pallets.
132pub type MiddsId = u64;
133
134/// Substrate-compatible MIDDS (Music Industry Decantralized Data Structure) interface definition.
135pub trait Midds: Parameter + Member + MaxEncodedLen {
136 const NAME: &'static str;
137
138 #[cfg(feature = "runtime-benchmarks")]
139 type BenchmarkHelper: benchmarking::BenchmarkHelperT<Self>;
140
141 /// Return the integrity hash (with Blake2) of the encoded MIDDS.
142 fn hash(&self) -> [u8; 32] {
143 Blake2_256::hash(&self.encode())
144 }
145
146 /// A function that a MIDDS can implement to enforce specific validation logic.
147 ///
148 /// # Errors
149 ///
150 /// Returns a dispatch error if the MIDDS data is invalid
151 fn validate(&self) -> DispatchResult {
152 Ok(())
153 }
154}
155
156pub mod pallet_prelude {
157 //! Prelude for pallet developers - contains all runtime types and commonly used imports
158
159 // Runtime types (for Substrate/Pallets)
160 pub use super::{
161 musical_work::MusicalWork,
162 party_identifier::{Artist, Entity, PartyIdentifier, PartyType},
163 release::Release,
164 track::Track,
165 };
166
167 // Shared types
168 pub use super::shared::{Country, Date, Key, Language};
169
170 // Core types
171 pub use super::{Midds, MiddsId};
172
173 // MIDDS-specific types
174 #[cfg(feature = "std")]
175 pub use super::shared::{ConversionError, Validatable, ValidationError};
176}