Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

jobs:
build:
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
smalltalk: [Pharo64-14, Pharo64-13, Pharo64-12, Pharo64-11, Pharo64-10]

runs-on: ${{ matrix.os }}
name: ${{ matrix.smalltalk }} on ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- name: Setup SmalltalkCI
uses: hpi-swa/setup-smalltalkCI@v1
with:
smalltalk-version: ${{ matrix.smalltalk }}
- name: Load and Test
run: smalltalkci -s ${{ matrix.smalltalk }}
shell: bash
timeout-minutes: 15
31 changes: 0 additions & 31 deletions .github/workflows/matrix.yml

This file was deleted.

13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

135 changes: 95 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,110 @@
# Containers-KeyedTree
An implementation of KeyedTree
A hierarchical data structure that provides path-based access to nested elements with dictionary-like functionality. Perfect for configuration management, file system structures & hierarchical data organization.

[![Build Status](https://travis-ci.com/Ducasse/Containers-KeyedTree.svg?branch=master)](https://travis-ci.com/Ducasse/Containers-KeyedTree)
[![Coverage Status](https://coveralls.io/repos/github//Ducasse/Containers-KeyedTree/badge.svg?branch=master)](https://coveralls.io/github//Ducasse/Containers-KeyedTree?branch=master)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)]()
[![Pharo version](https://img.shields.io/badge/Pharo-7.0-%23aac9ff.svg)](https://pharo.org/download)
[![Pharo version](https://img.shields.io/badge/Pharo-8.0-%23aac9ff.svg)](https://pharo.org/download)
<!-- [![Build status](https://ci.appveyor.com/api/projects/status/1wdnjvmlxfbml8qo?svg=true)](https://ci.appveyor.com/project/olekscode/dataframe) -->
![Pharo Version](https://img.shields.io/badge/Pharo-10+-blue)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

## What is a KeyedTree?
A KeyedTree is a specialized dictionary that allows nested structures where values can be accessed through path-based keys. Each node can contain both direct values and subtrees, enabling hierarchical data organization similar to file systems or nested configurations.

## Loading
The following script installs Containers-KeyedTree in Pharo.

## Example
To have an overview of the features this datastructure provide, have a look at the following code snippet (extracted from a unit test):
```smalltalk
Metacello new
baseline: 'ContainersKeyedTree';
repository: 'github://pharo-containers/Containers-KeyedTree/src';
load.
```

```st
firstLevelOneSubTree := CTKeyedTree new.
firstLevelOneSubTree
at: #two put: 'One-Two';
at: #three put: 'One-Three'.

tree := CTKeyedTree new.
tree
at: 1 put: firstLevelOneSubTree;
at: 2 put: 'Two'.

self assert: (tree atPath: #(1)) equals: firstLevelOneSubTree.
self assert: (tree atPath: #(1 two)) equals: 'One-Two'.
self assert: (tree atPath: #(1 three)) equals: 'One-Three'.
self assert: (tree atPath: #(2)) equals: 'Two'.
self should: [ tree atPath: #(2 4) ] raise: self defaultTestError.
self should: [ tree atPath: #(1 two three) ] raise: self defaultTestError.
self should: [ tree atPath: #(3) ] raise: self defaultTestError
## If you want to depend on it
Add the following code to your Metacello baseline or configuration:

```smalltalk
spec
baseline: 'ContainersKeyedTree'
with: [ spec repository: 'github://pharo-containers/Containers-KeyedTree/src' ].
```

## Loading
## Why use Containers-KeyedTree?

The following script installs Containers-Stack in Pharo.
KeyedTrees solve the problem of **organizing hierarchical data with efficient path-based access**. Perfect for configuration files, menu systems, and any data that naturally forms a tree structure.

```st
Metacello new
baseline: 'ContainersKeyedTree';
repository: 'github://pharo-containers/Containers-KeyedTree:v1.0/src';
load.
```
### Key Benefits
- **Hierarchical Organization**: Natural tree structure for nested data
- **Path-based Access**: Access deep elements with simple path arrays
- **Flexible Values**: Store any object type at any level
- **Merge Capability**: Combine trees intelligently
- **Dictionary Compatibility**: Inherits from Dictionary for familiar API

## Basic Usage

```smalltalk
"Create a hierarchical structure"
tree := CTKeyedTree new.

## If you want to depend on it
"Add simple values"
tree at: #name put: 'MyApp'.
tree at: #version put: '1.0.0'.

Add the following code to your Metacello baseline or configuration
"Create nested structures"
config := CTKeyedTree new.
config at: #host put: 'localhost'.
config at: #port put: 8080.
tree at: #server put: config.

"Access with paths"
tree atPath: #(server host). "=> 'localhost'"
tree atPath: #(server port). "=> 8080"
tree atPath: #(version). "=> '1.0.0'"
```
spec
baseline: 'ContainersKeyedTree'
with: [ spec repository: 'github://pharo-containers/Containers-KeyedTree:v1.0/src' ]

## Real-World Use Cases

```smalltalk
"Build a hierarchical menu structure for GUI Applications"
mainMenu := CTKeyedTree new.

"File menu"
fileMenu := CTKeyedTree new
at: #new put: 'Create New Document';
at: #open put: 'Open Document';
at: #recent put: (CTKeyedTree new
at: #doc1 put: '/path/to/recent1.txt';
at: #doc2 put: '/path/to/recent2.txt';
yourself);
at: #save put: 'Save Document';
at: #exit put: 'Exit Application';
yourself.

"Edit menu"
editMenu := CTKeyedTree new
at: #undo put: 'Undo Last Action';
at: #redo put: 'Redo Last Action';
at: #copy put: 'Copy Selection';
at: #paste put: 'Paste Content';
yourself.

"Tools menu with nested submenus"
toolsMenu := CTKeyedTree new
at: #preferences put: (CTKeyedTree new
at: #general put: 'General Settings';
at: #appearance put: 'Theme & UI';
at: #shortcuts put: 'Keyboard Shortcuts';
yourself);
at: #plugins put: 'Manage Plugins';
yourself.

mainMenu
at: #file put: fileMenu;
at: #edit put: editMenu;
at: #tools put: toolsMenu.

"Access menu items by path"
newAction := mainMenu atPath: #(file new). "=> 'Create New Document'"
recentDoc := mainMenu atPath: #(file recent doc1). "=> '/path/to/recent1.txt'"
themeSettings := mainMenu atPath: #(tools preferences appearance). "=> 'Theme & UI'"
```

## Contributing
This is part of the Pharo Containers project. Feel free to contribute by implementing additional methods, improving tests, or enhancing documentation.
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
Class {
#name : #BaselineOfContainersKeyedTree,
#superclass : #BaselineOf,
#category : #BaselineOfContainersKeyedTree
#name : 'BaselineOfContainersKeyedTree',
#superclass : 'BaselineOf',
#category : 'BaselineOfContainersKeyedTree',
#package : 'BaselineOfContainersKeyedTree'
}

{ #category : #baselines }
{ #category : 'baselines' }
BaselineOfContainersKeyedTree >> baseline: spec [

<baseline>
spec for: #pharo do: [
spec package: 'Containers-KeyedTree'.
spec package: 'Containers-KeyedTree-Tests' with: [ spec requires: #('Containers-KeyedTree') ]
]
]
spec for: #common do: [
spec package: 'Containers-KeyedTree'.
spec
package: 'Containers-KeyedTree-Tests'
with: [ spec requires: #( 'Containers-KeyedTree' ) ] ]
]
2 changes: 1 addition & 1 deletion src/BaselineOfContainersKeyedTree/package.st
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Package { #name : #BaselineOfContainersKeyedTree }
Package { #name : 'BaselineOfContainersKeyedTree' }
Loading
Loading