First off, thank you for considering contributing to DataStructuresKit! This library aims to fill gaps in the Swift Standard Library with production-ready, performance-optimized data structures.
- Code of Conduct
- Getting Started
- Development Principles
- Pull Request Process
- Coding Standards
- Testing Requirements
- Documentation
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
- Fork the repository
- Clone your fork:
git clone https://github.com/hoseiocean/DataStructuresKit.git - Read the ADR documents in
/Documentation/ADR/to understand existing design decisions - Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes
- Run tests:
swift test - Commit and push your changes
- Open a Pull Request
DataStructuresKit follows strict software engineering principles. All contributions must adhere to:
Write tests first. Every new feature or bug fix must start with a failing test.
- Write a failing test that defines the expected behavior
- Write the minimum code to make the test pass
- Refactor while keeping tests green
Favor protocols over inheritance. Data structures should conform to relevant Swift protocols:
SequenceandCollectionwhere applicableEquatable,Hashable,Codablewhen appropriateSendablefor thread-safety guarantees
- Single Responsibility: Each type has one reason to change
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable for their base types
- Interface Segregation: Prefer small, focused protocols
- Dependency Inversion: Depend on abstractions, not concretions
- Meaningful, intention-revealing names
- Small, focused functions (ideally < 20 lines)
- No comments to explain bad code — rewrite the code instead
- Self-documenting code with clear abstractions
Extract common patterns into shared utilities or protocol extensions. Avoid copy-paste code.
Choose the simplest solution that works. Avoid over-engineering and premature abstraction.
Don't add functionality until it's actually needed. No speculative features.
Validate inputs early. Use precondition for programmer errors and throw errors for recoverable failures. Never silently ignore invalid states.
-
For new data structures, follow the existing ADR guidelines in
/Documentation/ADR/, ensuring your implementation addresses:- Copy semantics (value type with COW vs reference type) — see ADR-001
- ABI stability considerations — see ADR-002
- Performance characteristics and complexity guarantees — see ADR-003
-
Ensure all tests pass with
swift test -
Update documentation for any public API changes
-
Follow the commit message convention:
type(scope): description [optional body]Types:
feat,fix,docs,refactor,test,chore -
Request review from maintainers
-
Address feedback promptly and constructively
- Use Swift's official API Design Guidelines
- 4 spaces for indentation (no tabs)
- Maximum line length: 120 characters
- Use
// MARK: -to organize code sections
- Types:
UpperCamelCase - Functions, properties, variables:
lowerCamelCase - Protocols describing capabilities:
-able,-ible, or-ingsuffix - Acronyms: uppercase when alone (
HTTP), lowercase in compounds (httpRequest)
- Default to
privateorinternal - Only expose
publicAPI that is intentional and documented - Use
@usableFromInline internalfor performance-critical inlinable code
- Document time and space complexity with
/// - Complexity: O(...) - Prefer
O(1)operations where possible - Use Copy-on-Write for value types with heap storage
- Profile before optimizing
We use Swift Testing framework exclusively.
@Suite("DataStructure Tests")
struct DataStructureTests {
@Test("initialization creates empty structure")
func initialization() {
// Arrange, Act, Assert
}
@Suite("insertion operations")
struct InsertionTests {
@Test("insert adds element")
func insertAddsElement() { }
}
}- Minimum 90% code coverage for new code
- All public API must have tests
- Include edge cases: empty collections, single element, large datasets
- Test both success and failure paths
Use descriptive test names that explain the expected behavior, not the implementation.
Every public symbol must have documentation comments:
/// A last-in, first-out (LIFO) collection.
///
/// Use a stack when you need to access elements in reverse order of insertion.
///
/// - Complexity: Push and pop operations are O(1).
///
/// ## Example
///
/// ```swift
/// var stack = Stack<Int>()
/// stack.push(1)
/// stack.push(2)
/// print(stack.pop()) // Optional(2)
/// ```
public struct Stack<Element> { }- Brief description
- Detailed explanation (when needed)
- Complexity annotations for all operations
- Usage examples for non-trivial APIs
- Parameter and return value descriptions
Feel free to open an issue for questions or discussions about potential contributions.
Thank you for helping make DataStructuresKit better!