# Packages, Modules and Crates

Projects should generally group related code/function together this increases code organization

packages can contain multiple binary codes/files or a library crate

very large projects should be done with interrelated packages that all update should be done using cargo workspaces

encapsulation is useful because you don't need to worry about its implementation
this is good for reusing code

rust has features for your code's organization, which parts are exposed, which details are private and what names are in each scope in the program

These features are known collectively as the ``module system`` they include
- [**Packages**](Packages.md): A feature of Cargo that allows you to build, test and share crates
- [**Crates**](Crates.md): A tree of modules that produces a library or an executable
- [**Modules** and **use**](Modules%20and%20Use.md): lets you control the organization, scope and privacy of paths
- [**Paths**](Paths.md): A way of naming an item, such as a struct, function or module

## Best Practices for Packages with a Binary and a Library
A package can contain both a main.rs binary crate root and a lib.rs library crate root and both crates will have the package name by default

the binary crate will have just enough to start and executable that calls code within the library allow for other projects to benefit by just using the library part of the package for most of the functionality

The module tree should be defined in src/lib.rs then any items can be used in the binary crate by starting paths with the package name.

The binary crate then becomes a user of the library crate, it can only use the public API, which helps you design a good API by being both the author and client

## Public Structs Enums, Functions and Modules
This can be done by using the ``pub`` keyword
Everything is private by default to other code
### Module
This holds code that can be in a different file
``mod`` keyword
normally defined in the src/lib.rs file where the module tree is stored
ex.
```rust
pub mod Name_of_module {
 fn private_function () {}
}

pub mod Name_of_mod; // should be located in Name_of_mod.rs or in name_of_mod/mod.rs or in parent_mod/name_of_mod/child.rs
```

### Function
can be in a impl block or by itself just add ``pub`` keyword in front
Should be in a mod block so that the module can be used
ex.
```rust
pub fn public_function () {}

pub mod name_of_mod {
	pub fn example_pub_function () {}
}
```

### Struct
This only makes the use of the struct public but not the data stored inside it each needs to be declared as public same with associated functions
can have its own impl, function inside must be explicitly public in order to call 
if any data inside is private then a constructor MUST BE USED
ex.<img style="height:5svh" src="https://doc.rust-lang.org/book/img/ferris/does_not_compile.svg" />
```rust
pub struct PublicStruct {}

pub mod name_of_mod {

	pub struct ExampleStruct {
		pub x: i8,
		y: u16,
	}
	
	impl ExampleStruct {
		pub fn getter_example_struct (&self) -> i8 {
				x
			}
		}
	}
}

// --snip--
// consumption
// this is not VALID y must be pub in order to write to
// this needs a contructor
let use_of_struct = crate::name_of_mod::ExampleStruct {
	x: 8,
	y: 16, // not valid should be done by a fn that has access
}
println!("{}", use_of_struct.getter_example_struct());
```
<img style="height:5svh" src="https://doc.rust-lang.org/book/img/ferris/does_not_compile.svg" />
if this compiled this would output 8
### Enum
This does not require the variants be be made public in order to use
variants are pub by default if enum is
ex.
```rust
pub mod name_of_mod {
	pub enum ExampleEnum {
		Variant1(i8),
		Variant2(i16),
	}
}

// --snip--
// consumption
let enum1 = crate::name_of_mod::Variant1(8);
```